Embed in plain HTML
No framework, no build step: a mount element with data-* config and one
script tag. The widget finds every [data-booking-widget] element on load
and mounts the full booking flow into a Shadow DOM — your page's CSS and the widget's
never collide.
This is the complete examples/plain-html/index.html host from the repo,
verbatim:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Reel Time Charters — Book a trip</title>
<style>
body { font-family: ui-sans-serif, system-ui, sans-serif; margin: 0; background: #eef2f6; color: #0f172a; }
.page { max-width: 720px; margin: 0 auto; padding: 40px 16px; }
.hero h1 { font-size: 28px; margin: 0 0 6px; }
.hero p { color: #475569; margin: 0 0 28px; }
.mount { display: flex; justify-content: center; }
</style>
</head>
<body>
<div class="page">
<div class="hero">
<h1>Reel Time Charters</h1>
<p>Inshore & offshore fishing out of the marina. Book your trip below.</p>
</div>
<!-- The ONLY integration the operator does: this div + one script tag.
data-* attributes configure it; the widget auto-mounts on load. -->
<div
class="mount"
data-booking-widget
data-api-base="http://localhost:3010"
data-publishable-key="REPLACE_WITH_PK"
></div>
</div>
<script src="./widget.global.js"></script>
</body>
</html> Notes
-
Replace
data-api-basewith your API origin anddata-publishable-keywith yourpk_…key. If the page is served from the same origin as the API, omitdata-api-baseentirely — the widget falls back to relative URLs. -
The example loads
./widget.global.jsfrom its own folder; in production load it from the API origin (it's served alongside the API) or self-host the bundle. -
Serve the embed from a page you control: the widget sends the key and the customer's
contact details to whatever origin
data-api-basenames, so the host page's integrity matters. -
Add
data-trip-type-id="tt_…"to open directly on one trip type.
Want it to match your site? See Theming the widget.