Developers
Script reference
Everything embed.js does on your page, the data-mosh attributes, deep links, the window.Mosh API and the events it fires.
Loading the script
<script async src="https://mosh.events/embed.js"></script>
Load it once per page, anywhere. It runs on DOMContentLoaded (or immediately if the DOM is ready), binds the markers below, and sets window.Mosh. Loading it twice is harmless; the second copy exits.
The script's origin (https://mosh.events) is where the popup content comes from.
Plain links (no attributes)
Any <a href> pointing at your booking page opens the popup:
https://mosh.events/v/<slug>/book
https://mosh.events/v/<slug>/book?package=<package>&date=YYYY-MM-DD&guests=20
Both absolute and /v/<slug>/book relative forms match. Site builders can't add attributes to their native buttons, but they can always set a button's URL, so this is the mode most venues use. ?package=, ?date= and ?guests= on the link are passed through to the popup.
Links added after load are picked up by a MutationObserver, so single-page apps and Wix work without extra wiring.
Attributes
For full control, mark any element:
| Attribute | On | Meaning |
|---|---|---|
data-mosh-book="<slug>" | Any element | Opens the booking popup for that venue. The element's own href, if any, is the no-JS fallback. |
data-mosh-package="<package slug or id>" | Same element | Preselects a package and skips the Options step. |
data-mosh-date="YYYY-MM-DD" | Same element | Preselects a night. |
data-mosh-guests="20" | Same element | Sets the party size, so the Options step shows only packages that fit 20. |
<a href="https://mosh.events/v/your-venue/book?package=back-room"
data-mosh-book="your-venue"
data-mosh-package="back-room">Book the Back Room</a>
Deep links
?package= accepts the package's slug (its name, lowercased and hyphenated: back-room) or its id. ?date= is YYYY-MM-DD in the venue's timezone. ?guests= is the party size; with a date it lands the guest straight on the options that fit that many people (a package whose range is 10–40 is hidden for guests=50). Concierge adds all three when it sends a guest the booking link. All work on the plain link and in the attributes.
How the popup behaves
A fixed overlay with a 520×760 card (full-screen under 640px) and an iframe inside. The host page's scroll is locked while it's open; Escape, the × button, or clicking the backdrop closes it. Focus moves into the iframe and returns to the clicked element on close. prefers-reduced-motion disables the transitions.
Cmd/Ctrl/Shift-click and middle-click are left alone, so "open in new tab" still works.
Floating button
data-mosh-fab="<slug>" on the script tag adds a fixed "Book" button bottom-right on every page; data-mosh-fab-label sets its text. It's a normal data-mosh-book element underneath.
window.Mosh
Set once the script runs:
| Member | Type | Description |
|---|---|---|
Mosh.open(opts) | (opts) => boolean | Opens the popup. Returns false if opts.venue is missing. |
Mosh.close() | () => void | Closes the popup. |
Mosh.origin | string | The origin the popup loads from. |
Mosh.__v | number | Script version (used to prevent double loads). |
window.Mosh.open({
kind: "book", // optional; "book" is the default
venue: "your-venue", // required: your slug
package: "back-room", // optional: package slug or id
date: "2026-11-14", // optional: YYYY-MM-DD
});
Call it from your own click handler, a menu, or a countdown.
Events
MoshReady
Dispatched on document once the script has bound the page's markers. Use it if you need to call Mosh.open as early as possible:
document.addEventListener("MoshReady", () => {
// window.Mosh is ready
});
If the script might already be loaded, check window.Mosh?.__v first.
mosh:complete
When a booking completes inside the popup, a bubbling CustomEvent named mosh:complete is dispatched on the element that opened it (or on document for Mosh.open()):
document.addEventListener("mosh:complete", (e) => {
const { kind, id } = e.detail; // kind: "book", id: the booking id
analytics.track("Booking completed", { id });
});
The event carries only the kind and the booking id, no guest details.
How the popup closes itself
The popup tells the host to close (after completion, on Escape inside the iframe, or via its own close control) by posting a mosh:close message. You don't need to handle it; the script does.
What happens if the script fails
If the script is blocked or fails before the popup opens, the link navigates normally to your hosted booking page. The guest can always book.
Caching
embed.js is served with a short cache during active development; a versioned long-lived URL will follow when it stabilizes. Don't self-host a copy or you'll stop getting fixes.