Embeddable Widget
Drop-in booking widget for any website with one script tag.
Embeddable Widget
@astrocal/widget is a drop-in booking UI for any website. It renders a full calendar, time slot picker, and booking form inside a Shadow DOM — so it works on any page without CSS conflicts.
Installation
bash npm install @astrocal/widget bash pnpm add @astrocal/widget bash yarn add @astrocal/widget html <script src="https://cdn.astrocal.dev/widget/latest/astrocal.js"></script>
Quick Start
Popup Mode
Open a booking modal with one call:
import { open } from "@astrocal/widget";
open({
eventTypeId: "your-event-type-id",
mode: "popup",
});Inline Mode
Mount the widget into a container element:
import { open, destroy } from "@astrocal/widget";
// Mount
open({
eventTypeId: "your-event-type-id",
mode: "inline",
target: "#booking-container",
});
// Clean up when done
destroy("#booking-container");CDN (No Build Step)
For sites without a bundler, load the widget via a script tag:
<script src="https://cdn.astrocal.dev/widget/latest/astrocal.js"></script>
<script>
Astrocal.open({
eventTypeId: "your-event-type-id",
mode: "popup",
});
</script>Or use auto-initialization with data attributes — no JavaScript required:
<script src="https://cdn.astrocal.dev/widget/latest/astrocal.js"></script>
<div data-astrocal-event-type-id="your-event-type-id" data-astrocal-mode="inline"></div>Configuration
| Property | Type | Default | Description |
|---|---|---|---|
eventTypeId | string | required | Event type UUID to display |
apiUrl | string | "https://api.astrocal.dev" | API base URL |
mode | "inline" | "popup" | "popup" | Render mode |
target | string | HTMLElement | — | DOM element or CSS selector (inline mode) |
timezone | string | auto-detected | IANA timezone override |
theme | ThemeConfig | — | CSS custom property overrides |
colorScheme | "light" | "dark" | "auto" | "auto" | Color scheme |
demo | boolean | false | Demo mode (mock data, no API calls) |
onBookingCreated | (booking: BookingResult) => void | — | Booking success callback |
onError | (error: WidgetError) => void | — | Error callback |
onClose | () => void | — | Popup close callback |
API
open(config)
Opens the booking widget. In popup mode, creates a modal overlay. In inline mode, mounts into the target element.
close()
Closes the popup widget if open. No-op if no popup is active.
destroy(target)
Destroys an inline widget mounted on a target element. Removes the Shadow DOM and cleans up all resources.
autoInit()
Scans the DOM for elements with data-astrocal-* attributes and mounts widgets automatically. Called automatically when using the CDN script tag.
Theming
Customize the widget appearance with CSS custom properties:
open({
eventTypeId: "your-event-type-id",
theme: {
primaryColor: "#6366f1",
primaryHoverColor: "#4f46e5",
borderRadius: "12px",
fontFamily: "Inter, sans-serif",
},
});| Property | CSS Custom Property | Description |
|---|---|---|
primaryColor | --astrocal-primary | Primary action color |
primaryHoverColor | --astrocal-primary-hover | Primary hover color |
headingColor | --astrocal-heading | Heading text color |
backgroundColor | --astrocal-bg | Widget background |
textColor | --astrocal-text | Body text color |
borderColor | --astrocal-border | Border color |
borderFocusColor | --astrocal-border-focus | Focused border color |
borderRadius | --astrocal-radius | Border radius |
fontFamily | --astrocal-font | Font family |
The widget uses Shadow DOM isolation, so your site's styles won't affect it and vice versa.
SSR / Server-Side Rendering
The package is safe to import in Node.js (Next.js, Nuxt, etc.). The autoInit() function is guarded and will not run on the server. open() and destroy() require a browser environment. close() is a silent no-op on the server.
import { open } from "@astrocal/widget";
// Only call in browser context
if (typeof window !== "undefined") {
open({ eventTypeId: "..." });
}Using React? The @astrocal/react package wraps this widget with proper
lifecycle management — mount, unmount, and prop updates are handled automatically.
Next Steps
- React SDK — React wrapper with provider and hooks
- Quickstart — REST API basics
- API Reference — Full endpoint documentation