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.

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:

AttributeOnMeaning
data-mosh-book="<slug>"Any elementOpens 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 elementPreselects a package and skips the Options step.
data-mosh-date="YYYY-MM-DD"Same elementPreselects a night.
data-mosh-guests="20"Same elementSets 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>

?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:

MemberTypeDescription
Mosh.open(opts)(opts) => booleanOpens the popup. Returns false if opts.venue is missing.
Mosh.close()() => voidCloses the popup.
Mosh.originstringThe origin the popup loads from.
Mosh.__vnumberScript 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.