Embed in Astro

Astro pages render to static HTML, which is the widget's home turf: emit the [data-booking-widget] mount element with its data-* config and include the script with is:inline. No island, no client directive — the widget script does its own mounting.

This is the complete examples/astro/src/pages/index.astro host from the repo, verbatim:

---
// Astro renders this page to static HTML. The widget auto-mounts from the
// [data-booking-widget] div + the inline script tag — no host-framework coupling.
const apiBase = import.meta.env.PUBLIC_API_BASE ?? "http://localhost:3010";
const pk = import.meta.env.PUBLIC_PK ?? "";
---

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Astro host — Reel Time Charters</title>
  </head>
  <body style="font-family: system-ui, sans-serif;">
    <main style="max-width: 720px; margin: 0 auto; padding: 40px 16px;">
      <h1>Reel Time Charters — Astro host</h1>
      <p style="color:#475569;">The widget auto-mounts from the data-attributes below.</p>
      <div data-booking-widget data-api-base={apiBase} data-publishable-key={pk}></div>
    </main>
    <script src="./widget.global.js" is:inline></script>
  </body>
</html>

Notes

  • is:inline matters: it stops Astro from bundling/hoisting the script, so it loads exactly like a plain script tag and finds the mount element it expects.
  • The example reads PUBLIC_API_BASE / PUBLIC_PK at build time; both are public values.
  • In production load widget.global.js from the API origin rather than a local copy.

Want it to match your site? See Theming the widget.