How to use Google Tag Manager with Resos
In this article
This guide explains how to capture booking events from the Resos widget using Google Tag Manager on your own website.
Why GTM can’t load directly on the booking page
For security reasons, it is not possible to load a custom Google Tag Manager container on the Resos-hosted booking page. GTM containers can execute arbitrary code, which would be a security risk on a shared platform.

Instead, Resos pushes events to the dataLayer and sends postMessage events that your website can capture.
Prerequisites
- The Marketing & Analytics add-on must be activated. See How to set up Marketing & Analytics.
- The Resos booking widget embedded on your own website (where GTM is already installed)
Option 1: Embed the widget on your website
If you embed the Resos booking widget on your website where GTM is already installed, booking events are automatically pushed to the dataLayer. No extra configuration is needed - your GTM triggers will pick them up.
dataLayer event format
Each booking step pushes an event to window.dataLayer with a nested resosBooking block (the full block only appears on events that carry booking details):
{
event: "ResosBookingComplete",
event_category: "Resos",
resosBooking: {
guests: 4,
date: "2026-04-15",
time: "19:00",
bookingId: "abc123",
value: 1000,
currency: "EUR",
country: "DK",
newCustomer: true
}
}
When the guest has granted marketing consent, ResosBookingComplete also includes a resosUser block with SHA-256 hashed email and phone for Enhanced Conversions / Advanced Matching:
{
event: "ResosBookingComplete",
event_category: "Resos",
resosBooking: { /* ... */ },
resosUser: {
emailSha256: "…",
phoneSha256: "…"
}
}
Event names
| Event | Description |
|---|---|
ResosPageView | Page navigation within the widget |
ResosBookingStart | Booking widget opened |
ResosSelectExperience | Guest picked an experience on the experience step |
ResosSelectRegularBooking | Guest picked the regular (“A la carte”) booking option |
ResosSelectGuests | Guest count selected |
ResosSelectDate | Date selected |
ResosSelectTime | Time slot selected |
ResosAddPaymentInfo | Payment required (status changed to pending) |
ResosPayment | Payment captured (status settled or authorized) |
ResosBookingComplete | Booking confirmed |
ResosBookingCancel | Guest cancelled the booking |
ResosSendMessage | Guest sent an activity / chat message |
Example GTM trigger
Create a Custom Event trigger in GTM:
- Trigger type: Custom Event
- Event name:
ResosBookingComplete - This trigger fires on: All Custom Events
Then attach it to your conversion tag (Google Ads, Meta CAPI, etc.).
Option 2: Listen for postMessage events (iframe)
If the booking widget is loaded in an iframe, events are sent to the parent window via postMessage. This works even without GTM.
postMessage format
{
type: "ResosEventForwarder",
data: {
event: "ResosBookingComplete",
numGuests: 4,
bookingDate: "2026-04-15",
bookingTime: "19:00",
bookingId: "abc123",
value: 1000,
currency: "EUR"
}
}
Example listener
Add this script to your website to capture booking events and push them to the dataLayer for GTM:
window.addEventListener('message', function(event) {
if (event.data && event.data.type === 'ResosEventForwarder') {
var eventData = event.data.data;
// Push to dataLayer for GTM
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: eventData.event,
...eventData
});
}
});
Verify it worked
- Open your website with the embedded booking widget
- Open the browser console (in the widget iframe), run
resos.debug(), and reload the page - Look for
[gtag]and[postMessage]entries as you interact with the booking flow - In GTM, use Preview mode to verify that events appear in the debug panel