Embed in React (Vite)
The widget bundle is framework-agnostic: React loads the IIFE script once, then calls
window.BookingWidget.mount() on a node it owns. The widget renders inside
a Shadow DOM independently of React, with no shared dependencies and no version coupling.
mount() returns an unmount function, which is exactly what
useEffect wants as its cleanup.
This is the complete examples/react/src/main.tsx host from the repo,
verbatim:
import { StrictMode, useEffect, useRef } from "react";
import { createRoot } from "react-dom/client";
// The widget bundle is framework-agnostic: the React host loads the IIFE and calls
// mount() on a React-rendered node. The widget renders (Preact, in a shadow root)
// independently of React — no host-framework coupling. The `window.BookingWidget` ambient
// type lives in the sibling booking-widget.d.ts (generated from the widget's config-contract.ts
// by `bun run examples:sync-widget` — see that script for how it stays in sync).
const API_BASE = (import.meta.env.VITE_API_BASE as string) ?? "http://localhost:3010";
const PK = (import.meta.env.VITE_PK as string) ?? "";
function App() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (ref.current && window.BookingWidget) {
return window.BookingWidget.mount(ref.current, { apiBase: API_BASE, publishableKey: PK });
}
}, []);
return (
<main style={{ fontFamily: "system-ui, sans-serif", maxWidth: 720, margin: "0 auto", padding: "40px 16px" }}>
<h1>Reel Deal Sportfishing — React (Vite) host</h1>
<p style={{ color: "#475569" }}>The booking widget below is mounted by React via the widget's mount() API.</p>
<div ref={ref} />
</main>
);
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
); Notes
-
Load the widget script once in
index.html(e.g.<script src="https://api.example.com/widget.global.js"></script>) before the React bundle, sowindow.BookingWidgetexists when the effect runs. -
The example reads
VITE_API_BASE/VITE_PKfrom env; swap in your own config plumbing.apiBase: ""means same-origin relative URLs. -
Returning the
mount()result from the effect unmounts cleanly on re-render and under StrictMode's double-invoke.
Want it to match your site? See Theming the widget.