GA4 Datalayer requirements
DataLayer Requirements - Booqi.me Booking Platform
Below you will find our datalayer documentation.
.JSON Container
We have a generic .json file that you can import directly in your Google Tagmanager, to add all events and triggers.
You can use the following container:
Please make sure to fill in the empty placeholders were needed. Also always double check and test if everything is working for your specific case.
Datalayer Information
1. General Page View Events
1.1 Homepage View
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'page_view',
page_type: 'homepage',
page_category: 'booking',
language: 'de', // or detected language
user_type: 'guest' // or 'returning_customer'
});
1.2 Product View
dataLayer.push({
event: 'page_view',
page_type: 'product',
page_category: 'booking',
language: 'de', // or detected language
user_type: 'guest' // or 'returning_customer'
});
2. Product Interaction Events
2.1 Product View (Product Detail)
Trigger: When a user visits a product detail page (URL contains /product/).
dataLayer.push({
event: 'view_item',
ecommerce: {
currency: 'EUR',
value: 72.0,
items: [{
item_id: '1234567',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
item_variant: 'standard', // or venue-specific variants
price: 72.0,
quantity: 1,
item_type: 'adult',
booking_type: 'individual' // or 'group', 'subscription'
}]
}
});
For Group Products:
dataLayer.push({
event: 'view_item',
ecommerce: {
currency: 'EUR',
value: 650.0,
items: [{
item_id: '1234567',
item_name: 'Group Guided Tour',
item_category: 'Group Tickets',
price: 25.0,
quantity: 26,
item_type: 'group',
booking_type: 'group'
}]
}
});
2.2 Product List View
Trigger: When viewing multiple products on a category page (e.g., shop homepage).
dataLayer.push({
event: 'view_item_list',
ecommerce: {
item_list_id: 'admission-tickets',
item_list_name: 'Admission Tickets',
items: [{
item_id: '1234567',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
price: 72.0,
index: 0
},
{
item_id: '7654321',
item_name: 'All-inclusive Afternoon Ticket',
item_category: 'Admission Tickets',
price: 0.0, // varies by date
index: 1
}]
}
});
2.3 Product Click
Trigger: When a user selects a product on the category page.
dataLayer.push({
event: 'select_item',
ecommerce: {
items: [{
item_id: '1234567',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
price: 72.0,
index: 0
}]
}
});
3. Booking Funnel Events
3.1 Date Selection
Trigger: When a user confirms a visit date and proceeds to the next step (if date selection is available).
dataLayer.push({
event: 'date_selected',
visit_date: '2025-11-07',
visit_day: 'Friday',
price_adult: 72.0,
price_child: 36.0,
product_id: 'all-inclusive-day-ticket',
product_name: 'All-inclusive Day Ticket',
total_tickets: 2,
total_value: 108.0
});
3.2 Time Slot Selection
Trigger: When a user confirms a time slot and proceeds (if time slot selection is available).
dataLayer.push({
event: 'timeslot_selected',
course_date: '2025-11-13',
time_slot: '11:00 - 13:00',
course_type: '2h Ski Group Beginner',
participant_type: 'adult', // or 'child'
participant_age: '13+',
price: 60.0
});
4. Cart Events
4.1 Add to Cart
Trigger: When a user proceeds to checkout after selecting items.
dataLayer.push({
event: 'add_to_cart',
ecommerce: {
currency: 'EUR',
value: 108.0,
items: [{
item_id: '1234567',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
price: 72.0,
quantity: 1,
item_type: 'adult'
},
{
item_id: '7654321',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
price: 36.0,
quantity: 1,
item_type: 'child'
}]
}
});
5. Checkout Events
5.1 Begin Checkout
Trigger: When a user enters the checkout flow (personal-details step).
dataLayer.push({
event: 'begin_checkout',
ecommerce: {
currency: 'EUR',
value: 108.0,
items: [{
item_id: '1234567',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
price: 72.0,
quantity: 1,
item_type: 'adult'
},
{
item_id: '7654321',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
price: 36.0,
quantity: 1,
item_type: 'child'
}]
}
});
5.2 Add Shipping Info (Personal Details)
Trigger: When personal details are completed and the user can continue to payment.
dataLayer.push({
event: 'add_shipping_info',
ecommerce: {
currency: 'EUR',
value: 108.0,
items: [{
item_id: '1234567',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
price: 72.0,
quantity: 1
}]
},
user_data: {
email_address: 'user@example.com',
phone_number: '+31612345678',
first_name: 'Alex',
last_name: 'Example'
}
});
5.3 Purchase
Trigger: When a booking completes successfully and the user lands on the thank-you page. Ensure the event fires only once per confirmed purchase.
dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: 'T123456789',
affiliation: 'Venue Name',
value: 108.0,
tax: 0.0,
shipping: 0.0,
currency: 'EUR',
coupon: '',
items: [{
item_id: '1234567',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
item_variant: 'standard',
price: 72.0,
quantity: 1,
item_type: 'adult'
},
{
item_id: '7654321',
item_name: 'All-inclusive Day Ticket',
item_category: 'Admission Tickets',
item_variant: 'standard',
price: 36.0,
quantity: 1,
item_type: 'child'
}]
},
user_data: {
email_address: 'user@example.com',
phone_number: '+31612345678',
first_name: 'Alex',
last_name: 'Example'
}
});
6. Enhanced E-commerce Product Fields
Standard Product Object Structure
Include these fields when available.
{
item_id: 'unique-product-id',
item_name: 'Product Display Name',
affiliation: 'Venue Name',
coupon: '',
discount: 0.0,
index: 0,
item_brand: 'Venue Brand',
item_category: 'Admission Tickets',
item_category2: 'All-inclusive',
item_category3: '',
item_list_id: 'category-list-id',
item_list_name: 'Category Display Name',
item_variant: 'standard',
location_id: 'venue-location',
price: 72.0,
quantity: 1,
item_type: 'adult',
age_group: '13+',
visit_date: '2025-11-13',
time_slot: '11:00 - 13:00',
includes_equipment: true,
includes_food: true,
season: 'winter_2025',
booking_type: 'individual',
min_quantity: 25,
group_size: 26
}
7. Error Tracking
7.1 Booking Errors
Trigger: When a booking error occurs.
dataLayer.push({
event: 'booking_error',
error_type: 'availability', // or 'payment', 'validation', 'system'
error_code: 'NO_AVAILABILITY',
error_message: 'Selected date is fully booked',
product_id: 'all-inclusive-day-ticket',
step: 'date_selection' // or 'payment', etc.
});
8. Additional Tracking Recommendations
8.1 Session Information
Push once on initial page load.
dataLayer.push({
session_id: 'unique-session-id',
timestamp: '2025-11-03T14:30:00Z',
user_agent: navigator.userAgent,
viewport_size: '1920x1080',
device_type: 'desktop',
referrer: document.referrer
});
8.2 Price Monitoring
Track dynamic pricing changes.
dataLayer.push({
event: 'price_update',
product_id: 'all-inclusive-day-ticket',
previous_price: 108.0,
new_price: 123.0,
visit_date: '2025-11-08',
reason: 'weekend_pricing' // or 'peak_season', 'demand'
});
9. Implementation Notes
Best Practices
- Initialize
window.dataLayer = window.dataLayer || [];before any pushes. - Clear the ecommerce object with
dataLayer.push({ ecommerce: null });before each ecommerce push to prevent data pollution. - Fire events only after the corresponding user action completes.
- Implement schema validation for all
dataLayerevents during development. - Test in Google Tag Manager Preview mode and leverage the
dataLayerdebugger.
Data Quality Requirements
- Prices use
EURwith two decimal places. - Dates use ISO format (
YYYY-MM-DD). - Item IDs remain consistent and unique per product.
- Populate all required fields.
- Do not send PII unless explicitly consented and contractually required.
Priority Events for Initial Implementation
- Phase 1 (Critical):
page_view,view_item,add_to_cart,begin_checkout,purchase - Phase 2 (Important):
view_item_list,select_item,date_selected,form_error - Phase 3 (Nice to have): upsells, price monitoring, session tracking
10. Multi-tenant / White-label Considerations
For venues using Booqi, append venue context to all relevant events.
dataLayer.push({
event: 'page_view',
page_type: 'homepage',
venue: {
venue_id: 'venue-slug',
venue_name: 'Venue Name',
venue_type: 'indoor_ski', // or 'museum', 'attraction', etc.
venue_location: 'City, Country'
}
});
Include in ecommerce items:
affiliation: 'Venue Name',
location_id: 'venue-location'
11. Document Version History
- v1.0 (Nov 2025): Initial requirements derived from a reference booking flow, generalized for all Booqi shops.
Updated on: 21/11/2025
Thank you!
