Embedding the Booking UI
Use data attributes and showUI() to embed the Resytech booking modal on any page.
The booking UI opens as a full-screen modal. You can trigger it with HTML data attributes (zero JavaScript) or programmatically with showUI().
Data Attributes (No JavaScript)
Add data-resytech-* attributes to any clickable element. The library automatically binds click handlers on DOM ready.
<button
data-resytech-activity-id="activity-uuid"
data-resytech-equipment-id="equipment-uuid">
Book Now
</button>Clicking this button opens the booking modal with the specified activity and equipment pre-selected.
Available Data Attributes
| Attribute | Type | Description |
|---|---|---|
data-resytech-activity-id | string | Activity UUID to pre-select |
data-resytech-equipment-id | string | Equipment UUID to pre-select. Quantity defaults to 1. |
data-resytech-equipment-quantity | number | Quantity for the equipment in data-resytech-equipment-id. Defaults to 1. |
data-resytech-addons | string (JSON) | JSON array of {addonUuid, quantity} to attach to the equipment in data-resytech-equipment-id. |
data-resytech-equipment | string (JSON) | JSON array of EquipmentSelection. Use this for multi-equipment selections. Overrides the three attributes above. |
data-resytech-date | string | Date to pre-select (YYYY-MM-DD) |
data-resytech-duration | number | Duration in minutes |
data-resytech-time-start | string | Time slot start (ISO 8601 datetime) |
data-resytech-time-end | string | Time slot end (ISO 8601 datetime) |
data-resytech-price | number | Price for the time slot |
data-resytech-lock-schedule | "true" | When set to "true", hides the "Choose another date/time" link inside the modal so the customer can't swap the slot. With the modal's hardcoded SchedulingOnly nav mode, this makes the navbar empty (and self-hiding). |
data-resytech-gift-card | string (JSON), "", or "true" | Opens the modal in gift card purchase mode instead of the activity flow. Accepts an empty value or "true" for an empty form, or a JSON object matching GiftCardSelection to pre-fill amount and purchaser/recipient details. When this attribute is present, the activity-related attributes are ignored. See Gift Card Mode below. |
At least one of data-resytech-activity-id, data-resytech-equipment-id, data-resytech-equipment, or data-resytech-gift-card must be present for the element to be auto-bound. The location is always taken from the client's locationId config.
EquipmentSelection (and AddonSelection)
Each equipment selection describes one equipment item in the cart along with its quantity and any add-ons:
interface EquipmentSelection {
equipmentUuid: string;
quantity: number;
addons?: AddonSelection[];
}
interface AddonSelection {
addonUuid: string;
quantity: number;
}Minimal Example
Pre-select only the activity. The customer chooses equipment, date, and time in the modal:
<button data-resytech-activity-id="kayak-uuid">
Book a Kayak
</button>Fully Pre-Filled Example
Skip straight to checkout with everything pre-selected:
<button
data-resytech-activity-id="kayak-uuid"
data-resytech-equipment-id="single-kayak-uuid"
data-resytech-date="2025-07-15"
data-resytech-duration="120"
data-resytech-time-start="2025-07-15T10:00:00"
data-resytech-time-end="2025-07-15T12:00:00"
data-resytech-price="89.99">
Book: Single Kayak - Jul 15, 10am-12pm ($89.99)
</button>Equipment with Quantity and Add-ons
Pre-select two single kayaks plus a dry-bag add-on:
<button
data-resytech-activity-id="kayak-uuid"
data-resytech-equipment-id="single-kayak-uuid"
data-resytech-equipment-quantity="2"
data-resytech-addons='[{"addonUuid":"dry-bag-uuid","quantity":2}]'>
Book Two Kayaks + Dry Bags
</button>Locking the Schedule
When the parent page has already chosen the slot, add data-resytech-lock-schedule="true" to prevent the customer from changing it inside the modal:
<button
data-resytech-activity-id="kayak-uuid"
data-resytech-equipment-id="single-kayak-uuid"
data-resytech-date="2025-07-15"
data-resytech-duration="120"
data-resytech-time-start="2025-07-15T10:00:00"
data-resytech-time-end="2025-07-15T12:00:00"
data-resytech-price="89.99"
data-resytech-lock-schedule="true">
Confirm: Single Kayak - Jul 15, 10am-12pm ($89.99)
</button>This hides the "Choose another date/time" crumb inside the modal. The customer can still close the modal (X button, ESC, or click-outside) and pick a different slot from your own UI.
Multiple Equipment Selections
For carts that include more than one piece of equipment, use the JSON data-resytech-equipment attribute. It accepts an array of EquipmentSelection and takes precedence over data-resytech-equipment-id / -quantity / -addons:
<button
data-resytech-activity-id="kayak-uuid"
data-resytech-equipment='[
{"equipmentUuid":"single-kayak-uuid","quantity":2},
{"equipmentUuid":"tandem-kayak-uuid","quantity":1,"addons":[
{"addonUuid":"dry-bag-uuid","quantity":2}
]}
]'>
Book the Group Package
</button>Programmatic Usage with showUI()
Call showUI() directly for dynamic scenarios:
const client = window.resytech; // or your own instance
client.showUI({
activity: 'kayak-uuid',
equipment: [
{ equipmentUuid: 'single-kayak-uuid', quantity: 1 }
],
date: '2025-07-15',
durationMins: 120,
timeSlotStart: '2025-07-15T10:00:00',
timeSlotEnd: '2025-07-15T12:00:00',
timeSlotPrice: 89.99
});equipment is an array of EquipmentSelection — each entry carries the equipment UUID, quantity, and optional add-ons (with their own quantities). For example:
client.showUI({
activity: 'kayak-uuid',
equipment: [
{
equipmentUuid: 'single-kayak-uuid',
quantity: 2,
addons: [
{ addonUuid: 'dry-bag-uuid', quantity: 2 }
]
},
{
equipmentUuid: 'tandem-kayak-uuid',
quantity: 1
}
]
});String shorthand
If you only need to pre-select one equipment with quantity 1 and no add-ons, you can pass the equipment UUID as a string:
client.showUI({
activity: 'kayak-uuid',
equipment: 'single-kayak-uuid' // shorthand for [{ equipmentUuid: 'single-kayak-uuid', quantity: 1 }]
});Locking the schedule
Pass lockSchedule: true to hide the "Choose another date/time" link inside the modal — same effect as the data-resytech-lock-schedule attribute, just from JS:
client.showUI({
activity: 'kayak-uuid',
equipment: [{ equipmentUuid: 'single-kayak-uuid', quantity: 1 }],
date: '2025-07-15',
durationMins: 120,
timeSlotStart: '2025-07-15T10:00:00',
timeSlotEnd: '2025-07-15T12:00:00',
timeSlotPrice: 89.99,
lockSchedule: true
});See CheckoutRequest for the full option reference.
All properties are optional. Calling showUI() with no arguments opens the full booking flow from the start.
// Open with no pre-fill - customer picks everything
client.showUI();
// Pre-select just the activity
client.showUI({ activity: 'kayak-uuid' });
// Pre-select activity and date
client.showUI({ activity: 'kayak-uuid', date: '2025-07-15' });Gift Card Mode
The same modal can open directly to the gift card purchase flow instead of the activity flow. Pass a giftCard property on showUI() (or set the data-resytech-gift-card attribute). The presence of giftCard is the discriminator — when it's set, any activity/equipment pre-fill is ignored.
GiftCardSelection
All fields are optional. Omit giftCard entirely to stay on the standard activity flow; pass giftCard: {} (or data-resytech-gift-card="") to open the gift card flow with no pre-fills.
| Property | Type | Description |
|---|---|---|
amount | number | Pre-fill the gift card amount. If it matches one of the operator's flat-amount options, that option is selected; otherwise the form switches to custom-amount mode (if enabled). |
purchaser.name | string | Pre-fill the purchaser's full name |
purchaser.email | string | Pre-fill the purchaser's email |
purchaser.phone | string | Pre-fill the purchaser's phone number |
recipient.name | string | Pre-fill the recipient's name |
recipient.email | string | Pre-fill the recipient's email. Required at submit time when the operator has "send to recipient" enabled. |
recipient.message | string | Pre-fill the custom message sent with the gift card |
Programmatic (showUI)
// Open the gift card form with no pre-fills
client.showUI({ giftCard: {} });
// Open with just an amount pre-selected
client.showUI({ giftCard: { amount: 50 } });
// Pre-fill the full form
client.showUI({
giftCard: {
amount: 100,
purchaser: {
name: 'Alex Morgan',
email: 'alex@example.com',
phone: '+1 555 0100'
},
recipient: {
name: 'Jamie Lee',
email: 'jamie@example.com',
message: 'Happy birthday — enjoy a day on the water!'
}
}
});Data Attribute
The simplest form: bare attribute opens the gift card form with no pre-fills.
<button data-resytech-gift-card>Buy a Gift Card</button>Pre-fill with a JSON object matching GiftCardSelection:
<button data-resytech-gift-card='{
"amount": 100,
"recipient": { "email": "jamie@example.com" }
}'>
Send Jamie a $100 Gift Card
</button>Listening for Gift Card Events
Gift card purchases emit their own events — checkout:complete does not fire (no booking is created):
client.on('giftcard:complete', ({ giftCardCode, amount }) => {
console.log(`Sold gift card ${giftCardCode} for $${amount}`);
});
client.on('giftcard:close', () => {
// The customer dismissed the success view
});See Checkout Events for the full event reference.
Multiple Book Now Buttons
You can have as many booking buttons on a page as you need. Each one can pre-fill different options:
<script
src="https://js.resytech.com/latest/resytech.js"
data-resytech-location-id="YOUR_LOCATION_ID"
data-resytech-base-url="https://booking.yourdomain.com">
</script>
<h2>Kayak Rentals</h2>
<button data-resytech-activity-id="kayak-uuid" data-resytech-equipment-id="single-kayak-uuid">
Book Single Kayak
</button>
<button data-resytech-activity-id="kayak-uuid" data-resytech-equipment-id="tandem-kayak-uuid">
Book Tandem Kayak
</button>
<h2>Paddleboard Rentals</h2>
<button data-resytech-activity-id="paddleboard-uuid">
Book Paddleboard
</button>Each button opens the same modal but pre-selects different activities or equipment. Only one modal can be open at a time -- if the modal is already open, additional showUI() calls are ignored.
Real-World Examples
Activity Page with Book Now
<div class="activity-card">
<img src="/images/sunset-cruise.jpg" alt="Sunset Cruise">
<h2>Sunset Cruise</h2>
<p>Enjoy a 2-hour cruise along the coastline at golden hour.</p>
<p class="price">From $149 per person</p>
<button
class="btn-primary"
data-resytech-activity-id="sunset-cruise-uuid"
data-resytech-duration="120">
Book This Experience
</button>
</div>Pricing Table
<table>
<thead>
<tr>
<th>Duration</th>
<th>Price</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>1 Hour</td>
<td>$49</td>
<td>
<button
data-resytech-activity-id="jet-ski-uuid"
data-resytech-duration="60">
Book Now
</button>
</td>
</tr>
<tr>
<td>2 Hours</td>
<td>$89</td>
<td>
<button
data-resytech-activity-id="jet-ski-uuid"
data-resytech-duration="120">
Book Now
</button>
</td>
</tr>
<tr>
<td>Half Day</td>
<td>$159</td>
<td>
<button
data-resytech-activity-id="jet-ski-uuid"
data-resytech-duration="240">
Book Now
</button>
</td>
</tr>
</tbody>
</table>Calendar Integration
If you have your own calendar UI, open the booking modal when a user picks a date:
// Your calendar component calls this when a date is clicked
function onDateSelected(dateString) {
window.resytech.showUI({
activity: 'kayak-uuid',
date: dateString // e.g. '2025-07-15'
});
}Dynamic Button from API Data
Fetch activities from the API and generate buttons dynamically:
const api = new ResytechApi({
baseUrl: 'https://api.bookingui.com/v1',
cmsBaseUrl: 'https://cms.bookingui.com'
});
const init = await api.initialization.initialize({ identifier: 'my-session' });
init.activities.forEach(activity => {
const btn = document.createElement('button');
btn.textContent = `Book ${activity.name} - from $${activity.startingAtPrice}`;
btn.setAttribute('data-resytech-activity-id', activity.uuid);
document.getElementById('activity-list').appendChild(btn);
});
// Re-bind data attributes after adding new elements
// (auto-binding only runs once on DOM ready, so for dynamic elements use showUI() instead)
document.querySelectorAll('#activity-list button').forEach(btn => {
btn.addEventListener('click', () => {
window.resytech.showUI({
activity: btn.getAttribute('data-resytech-activity-id')
});
});
});Important Notes
- Auto-binding runs once on
DOMContentLoaded. If you add elements to the DOM after page load, useshowUI()programmatically or attach your own click handlers. - One modal at a time. If the modal is already open,
showUI()does nothing and logs a debug message. - The
locationproperty is always set from the client'slocationIdconfig. You do not need to set it in data attributes orshowUI()options.
