@rts-hr/careers
v0.1.5
Published
Embeddable React careers widget for RTS hiring platform
Downloads
40
Readme
@rts-hr/careers
Embeddable React widget that displays your job board and application form directly on your website. Connects to your RTS hiring platform tenant via the public API.
Installation
npm install @rts-hr/careersPeer dependencies (must already be in your project):
npm install react react-domQuick start
import { CareersWidget } from "@rts-hr/careers";
import "@rts-hr/careers/style.css";
function App() {
return <CareersWidget tenant="acme" />;
}That's it. The widget renders a searchable job list. Clicking a job shows the full description and application form.
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| tenant | string | — | Your tenant identifier (e.g. "acme"). Required when fetchFn is not provided. |
| apiBaseUrl | string | https://{tenant}.rts-hr.cc/api | Override the API URL. Useful for local development or custom domains. |
| fetchFn | (endpoint, options?) => Promise<Response> | — | Custom fetch function. When provided, tenant and apiBaseUrl are not needed — the caller controls all fetch logic. |
| disableTheme | boolean | false | Skip the built-in ThemeProvider + ScopedCssBaseline. Use when a parent component already provides an MUI theme. |
| theme | object | see below | Customize colors, font, and border radius. Ignored when disableTheme is true. |
| locale | "de" \| "en" | "de" | UI language. |
| initialJobId | number | — | Open a specific job on load instead of the job list. |
| onNavigate | (view, jobId?) => void | — | Called when the user navigates between list and detail views. |
| onApplicationSubmitted | (jobId, applicationId) => void | — | Called after a successful application submission. |
| maxHeight | number \| "auto" | "auto" | Constrain the widget height in pixels. Adds internal scrolling. |
Theme object
<CareersWidget
tenant="acme"
theme={{
primaryColor: "#FF6600", // Brand color (buttons, highlights)
fontFamily: "Inter, sans-serif",
borderRadius: 8, // In pixels
mode: "light", // "light" or "dark"
}}
/>All theme properties are optional. Unset values use sensible defaults.
Examples
Basic embed
import { CareersWidget } from "@rts-hr/careers";
import "@rts-hr/careers/style.css";
export default function CareersPage() {
return (
<div style={{ maxWidth: 1200, margin: "0 auto" }}>
<h1>Join our team</h1>
<CareersWidget tenant="acme" />
</div>
);
}Dark mode with custom brand color
<CareersWidget
tenant="acme"
theme={{ primaryColor: "#7c3aed", mode: "dark" }}
/>English locale
<CareersWidget tenant="acme" locale="en" />Deep-link to a specific job
// Opens job #42 directly with back button to return to the list
<CareersWidget tenant="acme" initialJobId={42} />Sync navigation with your router
import { useRouter } from "next/navigation";
function Careers() {
const router = useRouter();
return (
<CareersWidget
tenant="acme"
onNavigate={(view, jobId) => {
if (view === "detail" && jobId) {
router.push(`/careers/${jobId}`, { scroll: false });
} else {
router.push("/careers", { scroll: false });
}
}}
/>
);
}Track application submissions
<CareersWidget
tenant="acme"
onApplicationSubmitted={(jobId, applicationId) => {
analytics.track("application_submitted", { jobId, applicationId });
}}
/>Fixed height with scrolling
<CareersWidget tenant="acme" maxHeight={600} />Custom fetch function (e.g. adding auth headers)
If you already have a fetch wrapper that adds headers (like tenant ID or auth tokens), pass it via fetchFn. The widget will use it for all API calls instead of constructing its own.
import { usePublicFetch } from "@/lib/auth";
function Careers() {
const publicFetch = usePublicFetch();
return (
<CareersWidget
fetchFn={publicFetch}
disableTheme // skip widget's ThemeProvider when parent already provides one
/>
);
}Local development
Point the widget at your local API:
<CareersWidget
tenant="local"
apiBaseUrl="http://localhost:8000/api"
/>How it works
- The widget calls
GET {apiBaseUrl}/public/jobsto fetch active job listings and renders them as a searchable, filterable list with infinite scroll. - When a user clicks a job, it calls
GET {apiBaseUrl}/public/jobs/{id}to fetch the full description and displays it with an application form. - On form submission, it sends a
POST {apiBaseUrl}/applications/jobs/{id}/applywith the candidate's data and CV asmultipart/form-data.
All endpoints are public (no authentication). CORS is configured to allow requests from any origin on these endpoints.
Browser support
Works in all modern browsers (Chrome, Firefox, Safari, Edge). Requires React 18 or 19.
TypeScript
The package ships with full TypeScript declarations. Import the props type if needed:
import type { CareersWidgetProps } from "@rts-hr/careers";