Scheduling

Embed booking on your website

Add your Workspace369 booking page to any website inline or as a popup button with one script tag, fall back to a plain iframe, or drive it from JavaScript.

View as Markdown

Your booking page does not have to live only at 369.dev. Paste one snippet from Share & embed into your website and clients can book without leaving your site. The embed shows the same services, availability, and payment steps as the public page.

Choose an embed style

StyleBest for
InlineA dedicated booking page or section on your site; the booking flow renders in place and grows to fit its content
Popup buttonAny page on the site; a floating button opens the booking flow in an overlay
Plain iframeSite builders that block custom scripts; fixed height, no popup, no JavaScript API

All three come ready to copy from Share & embed with your workspace and page already filled in. Every embed shows a "Powered by Workspace369" credit line.

Add an inline booking page

  1. Open the booking page's Share & embed action and copy the inline snippet.
  2. Paste it into your site's HTML where the booking flow should appear.
<script src="https://369.dev/booking.js" data-booking
  data-workspace="WS_ID"
  data-page="SLUG" async></script>

WS_ID is your workspace ID and SLUG is the page's link slug; the snippet from Share & embed already contains both, and the default page needs no data-page at all. The frame sizes itself to the booking flow as the client moves through it, so it needs no fixed height.

Add a popup button

  1. Open the booking page's Share & embed action and copy the popup snippet.
  2. Paste it just before the closing </body> tag of every page where the button should appear, or into your site builder's site-wide footer or custom-code area so the button appears everywhere.
<script src="https://369.dev/booking.js" data-booking
  data-workspace="WS_ID"
  data-page="SLUG"
  data-mode="popup" data-label="Book now" data-color="#111827" async></script>

data-label sets the button text and data-color its color. The booking flow opens in an overlay that scrolls inside itself; the client closes it with the close control or by pressing Escape.

To open the popup from your own button or link instead, add data-w369-booking to any element on the page:

<a href="#" data-w369-booking>Book a consultation</a>

Use a plain iframe

  1. Open the booking page's Share & embed action and copy the iframe snippet.
  2. Paste it into your site's HTML where the booking flow should appear.
<iframe src="https://369.dev/ws/WS_ID/book/SLUG?embed=1" title="Book an appointment" width="100%" height="900" style="border:0;display:block" loading="lazy"></iframe>

Use this when your site builder strips or blocks script tags. The iframe cannot resize itself, so adjust height to fit the longest step of the booking flow. The popup mode, the data- attributes, and the JavaScript API are not available with a plain iframe.

Attributes reference

AttributeRequiredPurpose
data-bookingYesMarks the script tag as a booking embed
data-workspaceYesYour workspace ID
data-pageNoThe booking page slug; omit it for the default page
data-mode="popup"NoShows a floating button instead of an inline frame
data-labelNoThe popup button text; defaults to "Book now"
data-colorNoThe popup button color as a hex value
data-serviceNoStarts the flow with a service already selected
data-memberNoStarts the flow with a host already selected
data-themeNoApplies a specific theme to the embed
data-prefill-name, data-prefill-email, data-prefill-phoneNoPrefill the client's details

Advanced — data-service, data-member, and data-theme take internal identifiers and are meant for developer integrations; most sites should let the visitor choose.

Keep campaign attribution

utm_source, utm_medium, utm_campaign, utm_term, and utm_content on the URL of the page hosting the embed are forwarded to the booking page, so campaign links keep their attribution.

React to bookings from your page

The script installs a small JavaScript API on the page:

<button type="button" onclick="W369Booking.open({ prefill: { name: 'Ada Lovelace', email: 'ada@example.com' } })">Book an appointment</button>
<script>
  window.addEventListener('w369:booked', (event) => {
    const { bookingId, status, startMs } = event.detail;
    // record a conversion, show a thank-you message, and so on
  });
</script>
  • W369Booking.open({ page, service, member, theme, prefill }) opens the booking flow in the popup overlay. Every option is optional and overrides the matching script attribute; prefill takes { name, email, phone }.
  • W369Booking.close() closes the popup.
  • w369:booked fires on window when a client completes the flow. event.detail carries bookingId, status, and startMs, the appointment's start time in milliseconds.

Payments inside an embed

When a service requires a deposit or full payment, the embed does not try to take the card inside the frame. The client sees a Continue to secure payment button that opens Stripe Checkout at the top level of the browser window. After paying, the client lands on a confirmation page on 369.dev with a Back to example.com button, where example.com is your site's domain, that returns them to your website.

The slot stays held for 30 minutes during payment, exactly as on the public page.

Troubleshooting

SymptomCheck
Nothing rendersYour site builder may block custom scripts; confirm the script tag survived publishing, or switch to the plain iframe
"Booking is not available"The page is paused, or the last active page was paused or deleted. Resume it in Booking Pages
The frame is cut offInline embeds size themselves; a plain iframe needs a larger height; popups scroll inside the overlay

Continue to Manage booking requests.

Embeds always show "Powered by Workspace369". Deposits and full payments open Stripe Checkout in the top-level window and need a connected Stripe account.

Was this article useful?

Your answer helps us decide what to clarify next.