Once the booking widget is on your website, it tells the page what the guest is doing in it: the panel opening and closing, each screen of the booking, each answer, and the booking itself. Every one of these is a browser event on window, so your developer — or anyone who looks after your Google Tag Manager — can build a booking funnel, change the page when someone books, or send the steps to any analytics tool.
The events
| Event | When it fires | What event.detail adds |
|---|---|---|
| taptime:open | The floating booking panel opens. The inline form is always open, so it never sends this. | — |
| taptime:close | The floating panel closes, however the guest closes it. | — |
| taptime:step | A screen of the booking is shown. | step, step_index, step_count |
| taptime:choice | The guest answers a question on a screen. | step, field, value, label |
| taptime:booking | A booking is made. | confirmed, booking_id, event_id, party_size, service_name, value, currency |
| taptime:event | Every one of the above, a second time. | event — the name of the one it repeats: open, close, step, choice or booking |
Each event carries its data in event.detail. Two fields are always there: company — the value of data-company in your embed code — and booking_type: reservation for tables, appointment for services.
Listen for an event
Add a script to the same page as the widget, with window.addEventListener and the event’s name. It can go before or after the embed code. This one hides a “Book now” banner once a booking is confirmed:
<script>
window.addEventListener('taptime:booking', function (event) {
if (event.detail.confirmed) {
document.getElementById('book-banner').hidden = true;
}
});
</script>
confirmed is true when the booking is confirmed straight away, and false when it is a request your team still has to accept. value, with its currency, is the price of the service for an appointment, or the booking value you set for conversion tracking for a table — and null when there is neither.
Screens and answers
taptime:step names the screen in detail.step. Which screens a guest sees depends on what they book and on your settings:
- location — the guest picks one of your locations. Only when you have several and the widget is not tied to one.
- party — how many guests. Tables only.
- service and specialist — what to book and with whom. Appointments only.
- when — the day and time.
- seating, zone and table — indoor or outdoor, an area of the room, a particular table. Tables only, and only the choices you have turned on.
- details — the guest’s name and contact details.
- done — the confirmation screen, after the booking is made.
step_index and step_count are the numbers the guest sees at the top of the form, as in “2 of 5”. The location list and the confirmation screen are not numbered, so there both are null. Because the number of screens depends on your settings, check the step name rather than the number.
taptime:choice names the answer in detail.field: branchId, partySize, date, time, seating, zoneId, tableId, serviceId or specialistId. detail.value is what was chosen — a number, an id, a date as 2026-09-18 or a time as 2026-09-18 19:30 — and detail.label is what the guest read on the button, such as a service or location name. Choosing “any” sends a value of null.
Send every event to Google Tag Manager
One listener on taptime:event catches all of them. The script below pushes each one to the dataLayer as taptime_open, taptime_step, taptime_choice and so on, with the detail fields alongside. Paste it into a Custom HTML tag that fires on all pages, or straight into your site. Then build triggers, variables and a funnel in Tag Manager without touching the site again.
<script>
window.dataLayer = window.dataLayer || [];
window.addEventListener('taptime:event', function (event) {
window.dataLayer.push(Object.assign({ event: 'taptime_' + event.detail.event }, event.detail));
});
</script>
More examples
Send each screen to Google Analytics 4 as its own event, to see in a funnel exploration where guests stop. This needs GA4 installed on your page with gtag.js:
<script>
window.addEventListener('taptime:step', function (event) {
if (typeof gtag !== 'function') return;
gtag('event', 'booking_step', {
step: event.detail.step,
step_index: event.detail.step_index,
booking_type: event.detail.booking_type
});
});
</script>
Offer another way to book when a guest closes the panel without booking — here, by showing a hidden “Call us” block:
<script>
var booked = false;
window.addEventListener('taptime:booking', function () {
booked = true;
});
window.addEventListener('taptime:close', function () {
if (!booked) {
document.getElementById('call-us').hidden = false;
}
});
</script>
Check that it works
-
1
Open your published website
Many site builders do not run custom code in their editor, so use the live site.
-
2
Open the browser console
Right-click the page, choose Inspect, then open the Console tab.
-
3
Paste the line below and press Enter
It prints every widget event as it happens. It lasts until you reload the page.
-
4
Click through a test booking
Each screen and answer appears in the console, then the booking. Cancel the test booking from your board afterwards.
window.addEventListener('taptime:event', function (event) { console.log(event.detail.event, event.detail); });
Frequently asked
Do I need to turn the events on?
No. They fire whenever the widget is on the page. The “Report bookings to my website’s tags” switch only controls the automatic dataLayer push and your page’s own GA4 and Meta Pixel.
Can I read the guest’s name, phone or email from an event?
No. Events carry ids, times, the party size, the service and the booking value — never who is booking. For guest details, use the panel, a webhook or the REST API.
My listener never runs.
Check that the script is on the same page as the widget and that the event name is spelled exactly, colon included: taptime:step. In Tag Manager, make sure the Custom HTML tag is published and fires on all pages. Open the console and try the test line above to see whether events arrive at all.
Can my own script open or close the widget?
Yes. TapTime.open() opens the floating panel, or scrolls to the inline form, and TapTime.close() closes it. With two companies on one page, TapTime.open('your-company') opens that company’s widget.
Thank you — that helps us make these guides better.
Write to us and quote the page you were on. A person reads every message and answers in the language you wrote in.
Write to us