@openings-link/react-ui
v0.3.3
Published
Themed, drop-in React booking widget for Openings. Styled with CSS custom properties.
Maintainers
Readme
@openings-link/react-ui
Themed, drop-in React booking widget for the Openings platform.
Built on
@openings-link/react
(headless core). Styled with CSS custom properties — no Tailwind, no CSS
modules.
Install
npm install @openings-link/react @openings-link/react-uiQuick Start
import { BookingWidget } from "@openings-link/react-ui";
function App() {
return (
<BookingWidget
business="your-business-handle"
theme={{ accent: "#8B5CF6" }}
on={{
onBookingComplete: (result) => {
console.log("Booked!", result);
},
}}
/>
);
}CORS and apiBase
BookingWidget defaults to apiBase="https://api.openings.link".
If your frontend runs on a third-party domain, prefer a same-origin proxy route in your app and point the widget to that proxy:
<BookingWidget business="your-business-handle" apiBase="/api/openings" />This is the recommended setup for npm users to avoid browser CORS issues.
Full proxy templates: https://github.com/openings-link/openings-react/blob/main/docs/proxy-templates.md
Props
| Prop | Type | Description |
| ----------------------- | ---------------------------- | ------------------------------------------------------ |
| business* | string | Business handle (slug). Required. |
| apiBase | string | API base URL. Defaults to https://api.openings.link. |
| scheduleId | string | Pre-select a schedule (skip location picker). |
| memberId | string | Pre-select a staff member (show their availability). |
| theme | BookingTheme | Accent color, border radius, font, light/dark mode. |
| labels | Partial<BookingLabels> | Override any user-facing string for i18n. |
| features | BookingFeatures | Optional capabilities, such as rescheduling. |
| completionMode | "inline" \| "external" | Use external to handle confirmation in the host app. |
| apiClient | ApiClient | Custom API client for testing or mock data. |
| appointmentMetadata | Record<string, string> | Extra metadata stored on created appointments. |
| on | OpeningsCallbacks | Event callbacks for booking lifecycle. |
| onConsultationRequest | (member, services) => void | Custom handler for consultation services. |
| className | string | CSS class for the root container. |
Appointments created through the widget automatically include
source: "openings-react" metadata. Use appointmentMetadata for additional
string fields such as an integration or campaign id.
Custom Confirmation
By default, the widget shows its built-in confirmation scene after an appointment
is created. Use completionMode="external" when the host app should own the
confirmation page or modal:
<BookingWidget
business="your-business-handle"
completionMode="external"
on={{
onBookingComplete: (result) => {
router.push(`/appointments/${result.appointmentId}/confirmed`);
},
}}
/>onBookingComplete still fires as soon as appointment creation succeeds. In
external mode, the widget shows a brief completed state instead of rendering
the built-in confirmation scene while the host app handles navigation or opens a
custom modal.
Optional Rescheduling
Rescheduling is disabled by default. Enable it when you want returning customers with upcoming appointments to choose between booking a new appointment and rescheduling an existing one:
<BookingWidget
business="your-business-handle"
features={{ rescheduling: true }}
on={{
onRescheduleComplete: (result) => {
console.log("Rescheduled!", result);
},
}}
/>The widget only shows appointment details after the customer verifies with the reschedule lookup code returned by the Openings API.
Theme
{
accent?: string; // Primary color (default: "#000000")
radius?: number; // Border radius in px (default: 8)
fontFamily?: string; // Font family (default: system)
mode?: "light" | "dark" | "auto";
}All CSS custom properties are prefixed --openings-*.
Live Demo
License
MIT
