@arkipay/booking-widget
v0.1.0
Published
Embeddable React booking widget for the ArkiPay / EasyAppts appointment platform. Drop-in BookingProvider + BookingWidget that inherits the host site's theme.
Downloads
127
Readme
@arkipay/booking-widget
Embeddable React booking widget for the ArkiPay / EasyAppts appointment platform. Drop
<BookingProvider> + <BookingWidget> into any React app and your customers can book
appointments against your tenant — service → provider → date/time → details → confirmation,
including the online-payment redirect. The widget inherits your site's theme automatically.
Install
npm install @arkipay/booking-widget
# or: pnpm add @arkipay/booking-widgetreact and react-dom (v18.3+ or v19) are peer dependencies you already have.
Quick start
import { BookingProvider, BookingWidget } from "@arkipay/booking-widget";
import "@arkipay/booking-widget/styles.css";
export default function BookingPage() {
return (
<BookingProvider publishableKey="pk_live_xxx">
<BookingWidget />
</BookingProvider>
);
}Use your publishable key (pk_live_… / pk_test_…) — never a secret key. The widget talks
only to the public API, so the key is safe to ship in browser code.
Next.js App Router
The package ships with a "use client" directive, so you can import it directly into a Server
Component — no wrapper needed.
Theming
The widget is fully tokenised. Every visual value resolves in this order (highest wins):
- an explicit
themeprop on<BookingProvider> - your site's own CSS design-system token (e.g.
--brand,--fg) — inherited automatically - tenant config (brand colour, configured in the platform)
- a built-in default
Inherit your site's theme (zero config)
If your site already defines any of these CSS variables on an ancestor element, the widget picks them up with no props at all:
| Host token | Controls | Widget token |
| ----------------- | -------------------------------- | -------------- |
| --brand / --accent | Primary / call-to-action colour | --ea-brand |
| --fg | Body text | --ea-text |
| --fg-muted | Secondary / hint text | --ea-muted |
| --border | Card & input borders | --ea-border |
| --bg-elevated | Card / input / surface background | --ea-surface |
| --danger | Error / validation colour | --ea-error |
| --radius-md | Corner radius | --ea-radius |
| --font-sans | Font stack | --ea-font |
// Your app already sets these on :root or a wrapper — the widget just follows.
<div style={{ "--brand": "#ff6b35", "--font-sans": "Inter, sans-serif" }}>
<BookingProvider publishableKey="pk_live_xxx">
<BookingWidget />
</BookingProvider>
</div>Explicit theme prop
For one-off overrides without a design system:
<BookingProvider
publishableKey="pk_live_xxx"
theme={{
brandColor: "#0f6b8c",
fontFamily: "Geist, system-ui, sans-serif",
borderRadius: "12px",
colorScheme: "system", // "light" | "dark" | "system"
}}
>
<BookingWidget />
</BookingProvider>Full theme surface: brandColor, onBrandColor, textColor, mutedColor, borderColor,
surfaceColor, errorColor, borderRadius, fontFamily, maxWidth, colorScheme.
Dark mode
Pass theme={{ colorScheme: "dark" }} (or "system" to follow prefers-color-scheme). If your
host already flips its own --fg / --bg-elevated tokens, the widget follows those instead — no
extra config needed.
Override via plain CSS
Because every element is scoped under .ea-booking-widget, you can override any token from your
own stylesheet without collisions:
.ea-booking-widget {
--ea-radius: 4px;
}
.ea-booking-widget .ea-btn-primary {
font-weight: 600;
}BookingProvider props
| Prop | Type | Default | Notes |
| ------------------ | -------------------------------------- | --------------------------- | ----- |
| publishableKey | string | — | Required. pk_live_… / pk_test_… |
| apiUrl | string | https://api.easyappts.com | Override for self-hosted / sandbox |
| theme | BookingTheme | {} | See Theming |
| locale | string | tenant default | e.g. "en" |
| onBooked | (appointment) => void | — | Fires on successful booking |
| initialServiceId / initialProviderId | string | URL ?service=/?provider= | Pre-select a step |
| className / style | string / CSSProperties | — | Applied to the widget root |
| botProtection | boolean | true | See below |
Bot protection
The widget uses Vercel BotID on the booking request. Full
protection requires the Vercel BotID proxy on your host. If you're not on Vercel, set
botProtection={false} — the API's server-side rate limiter remains the backstop.
Composing your own flow
Prefer your own layout? Import the step components and drive them with useBooking():
import {
BookingProvider, ServicePicker, ProviderPicker, DatePicker,
TimeSlotPicker, CustomerForm, ConfirmStep, BookedSummary, useBooking,
} from "@arkipay/booking-widget";A non-React / server integration can use the bundled API client directly:
import { createBookingClient } from "@arkipay/booking-widget";
const client = createBookingClient({ publishableKey: "pk_live_xxx" });
const config = await client.getTenantConfig();License
UNLICENSED — for use by ArkiPay customers integrating the booking platform.
