Inline Booking Embed
Embed the full Resytech booking UI inline on your page using the booking embed web component.
The <resytech-booking-embed> component embeds the Resytech booking UI directly on your page as an inline iframe. Unlike the modal widget which overlays the entire viewport, this component sits within your page layout — perfect for dedicated booking pages.
Basic Usage
<resytech-booking-embed
base-url="https://yourlocation.bookingui.com"
location-id="your-location-id">
</resytech-booking-embed>This renders the full booking flow inline: activity selection → equipment → duration → calendar → time slot → checkout.
Deep-Linking to an Activity
Skip the activity listing and open a specific activity's equipment selection:
<resytech-booking-embed
base-url="https://yourlocation.bookingui.com"
location-id="your-location-id"
activity-id="activity-uuid">
</resytech-booking-embed>Skip to Checkout
Pre-fill every step and land directly on the checkout page:
<resytech-booking-embed
base-url="https://yourlocation.bookingui.com"
location-id="your-location-id"
activity-id="activity-uuid"
equipment-id="equipment-uuid"
date="2025-07-15"
duration-mins="120"
time-start="2025-07-15T10:00:00"
time-end="2025-07-15T12:00:00"
price="89.99">
</resytech-booking-embed>Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
base-url | string | — | Required. Your bookingui.com URL (e.g. https://yourlocation.bookingui.com) |
location-id | string | — | Required. Your Resytech location UUID |
activity-id | string | — | Activity UUID to pre-select |
equipment-id | string | — | Equipment UUID to pre-select |
equipment-quantity | number | 1 | Quantity for the pre-selected equipment (must be ≥1 and not exceed the equipment's max). Ignored unless equipment-id is set. For multi-equipment carts use the selections property instead. |
date | string | — | Date to pre-select (YYYY-MM-DD) |
duration-mins | number | — | Duration in minutes |
time-start | string | — | Time slot start (ISO 8601) |
time-end | string | — | Time slot end (ISO 8601) |
price | number | — | Time slot price |
height | number | 700 | Initial iframe height in pixels (auto-resizes once loaded) |
nav-mode | string | SchedulingOnly | Navigation mode passed to the booking UI. None hides the navbar entirely; SchedulingOnly shows just the "Choose another date/time" link; omit (or any other value) for full breadcrumbs. |
lock-schedule | boolean | false | When true, suppress nav entries that let the customer change the booked date/time — the "Choose another date/time" crumb under SchedulingOnly, and the "Experience" link in default breadcrumbs. The Activity/Home crumbs still navigate; use nav-mode="None" to hide all navigation. |
show-close | boolean | false | Show the close (X) button in the booking UI header |
Multi-Equipment & Addon Pre-selection
For carts with more than one equipment item, per-equipment quantity, or pre-selected addons, set the JS selections property — HTML attributes can't carry nested data cleanly:
const embed = document.querySelector('resytech-booking-embed');
embed.selections = [
{
equipmentUuid: 'equipment-uuid-1',
quantity: 2,
addons: [
{ addonUuid: 'addon-uuid-1', quantity: 1 },
{ addonUuid: 'addon-uuid-2', quantity: 4 }
]
},
{
equipmentUuid: 'equipment-uuid-2',
quantity: 1
}
];selections takes precedence over equipment-id / equipment-quantity when both are set. The booking UI will skip activity/equipment/quantity selection and land the customer on checkout (assuming date, time-start, time-end, duration-mins, and price are also provided).
Each selection's quantity and addon quantity values are clamped server-side. If a stale or out-of-range value is sent, the dropdowns will display the server-capped value rather than the requested one.
Locking the Schedule
If you've sourced the date/time from your own UI and don't want the customer to change it inside the embed, set lock-schedule="true". Combine with nav-mode based on how visible you want the navbar:
<!-- Full breadcrumbs visible, but the "Experience" crumb is text-only -->
<resytech-booking-embed
base-url="https://yourlocation.bookingui.com"
location-id="your-location-id"
activity-id="activity-uuid"
equipment-id="equipment-uuid"
date="2025-07-15"
duration-mins="120"
time-start="2025-07-15T10:00:00"
time-end="2025-07-15T12:00:00"
price="89.99"
lock-schedule="true">
</resytech-booking-embed>
<!-- SchedulingOnly + lock-schedule = empty navbar (hidden) -->
<resytech-booking-embed
base-url="https://yourlocation.bookingui.com"
location-id="your-location-id"
activity-id="activity-uuid"
equipment-id="equipment-uuid"
date="2025-07-15"
duration-mins="120"
time-start="2025-07-15T10:00:00"
time-end="2025-07-15T12:00:00"
price="89.99"
nav-mode="SchedulingOnly"
lock-schedule="true">
</resytech-booking-embed>Customers can still navigate via Activity / Home in default nav-mode — those are "start over" actions, not date-change actions. Use nav-mode="None" if you need a fully locked-down chrome.
Auto Height
The embedded booking UI reports its content height to the parent. The component automatically resizes to match — no fixed height needed after the initial load. The height attribute only controls the container size before the first height message arrives.
Events
Listen for checkout lifecycle events on the component or any ancestor:
const embed = document.querySelector('resytech-booking-embed');
embed.addEventListener('checkout-ready', () => {
console.log('Booking UI is loaded and ready');
});
embed.addEventListener('checkout-complete', (e) => {
console.log('Booking confirmed!', e.detail.confirmationCode);
console.log('Total paid:', e.detail.price);
});
embed.addEventListener('checkout-close', () => {
console.log('User closed the booking UI');
});| Event | Detail | Description |
|---|---|---|
checkout-ready | {} | Booking UI has loaded |
checkout-complete | { confirmationCode, price } | Customer completed a booking |
checkout-return | { returnUrl } | Customer clicked the post-purchase Continue button. Informational -- the iframe navigates the top frame to returnUrl regardless |
checkout-close | {} | Customer clicked close (if show-close is enabled) |
gift-card-purchase-complete | { giftCardCode, amount } | Gift card purchased |
gift-card-close | {} | Customer dismissed the gift card success view |
membership-purchase-complete | { membershipNumber, planName } | Membership purchased |
membership-purchase-close | {} | Customer dismissed the membership success view |
Hybrid Approach
Use custom web components for browsing and the embed for checkout. This gives you full control over the discovery experience while leveraging the hosted checkout for payments:
<!-- Custom activity browsing -->
<resytech-activity-list></resytech-activity-list>
<!-- Inline booking embed (hidden initially) -->
<div id="booking-section" style="display: none;">
<resytech-booking-embed id="embed"
base-url="https://yourlocation.bookingui.com"
location-id="your-location-id">
</resytech-booking-embed>
</div>
<script>
document.addEventListener('activity-select', (e) => {
const embed = document.getElementById('embed');
embed.setAttribute('activity-id', e.detail.activity.uuid);
embed.reload();
document.getElementById('booking-section').style.display = 'block';
});
</script>Embed vs Modal Widget
Embed (<resytech-booking-embed>) | Modal (ResytechClient) | |
|---|---|---|
| Placement | Inline in page flow | Full-viewport overlay |
| Use case | Dedicated booking pages | "Book Now" buttons site-wide |
| Trigger | Always visible (or toggled) | Opens on click / showUI() |
| Close button | Hidden by default | Always shown |
| Scroll | Page scrolls naturally | Modal has its own scroll |
Reloading
Call .reload() to refresh the iframe with current attributes:
const embed = document.querySelector('resytech-booking-embed');
embed.setAttribute('activity-id', 'new-activity-uuid');
embed.reload();