Task 2
GA4 Event Spec via GTM
Rendered implementation flow for firing booking_completed after a patient reaches the booking thank-you page.
Assignment Brief
On the same WordPress site as Task 1, a patient completes a multi-step booking form ending on a thank-you page. Fire a GA4 custom event called booking_completed with booking_id, state, product_type, and value.
Rendered Event Flow
The diagram below shows exactly where the data layer push, GTM trigger, GA4 tag, validation, and de-dupe guard sit in the booking journey.
Data Layer Push on Thank-You Page
Push from the server-rendered thank-you template only after the booking has been persisted and the confirmation page has the final booking values.
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'booking_completed',
booking_id: 'BK-20260426-8F31',
state: 'FL',
product_type: 'initial_certification',
value: 99.00,
currency: 'USD'
});
</script>
- Do not push patient name, email, diagnosis, condition, appointment notes, or medical history.
- Render values from trusted server-side booking data, not client-entered form fields.
- Recommended page scope:
/booking/thank-you/or the production equivalent.
GTM Trigger
- Trigger type: Custom Event.
- Event name:
booking_completed. - Conditions: Page Path matches RegEx
^/booking/thank-you/?$. - Require
booking_id,state,product_type, andvalue. - Fire once per booking, not once per page refresh.
Data Layer Variables
DLV - booking_idmaps tobooking_id, version 2.DLV - statemaps tostate, version 2.DLV - product_typemaps toproduct_type, version 2.DLV - valuemaps tovalue, version 2 and should be treated as a number.DLV - currencymaps tocurrency; useUSD.
GA4 Event Tag
- Tag type: GA4 Event.
- Measurement ID: use the existing GA4 configuration variable or GTM constant variable.
- Event name:
booking_completed. - Event parameters: map each data layer variable to the same parameter name.
- Mark as a GA4 key event only after QA confirms no duplicate sends.
De-Dupe Guard
const key = `booking_completed_sent_${booking_id}`;
if (!sessionStorage.getItem(key)) {
sessionStorage.setItem(key, '1');
// allow GA4 event tag to fire
}
- Use
booking_idas the de-dupe key. - Prefer server-side single rendering where possible; use browser storage as the last-mile guard.
Validation
- Use GTM Preview mode and complete a test booking through the thank-you page.
- Confirm the data layer event appears once with all required parameters.
- Confirm the GA4 Event tag fires only on the custom event, not on page view.
- Open GA4 DebugView and verify
booking_completedwith expected values. - Refresh the thank-you page and verify the de-dupe guard prevents a second event.
Privacy and Failure Rules
- No PHI in GTM or GA4: no condition, symptom, diagnosis, notes, name, email, phone, or address.
- If a required parameter is missing, block the tag and log a non-PII warning in staging.
- If
valuecannot be parsed as a number, block revenue reporting until corrected. - Use separate
product_typevalues forinitial_certificationandrenewal.
Open Question / Assumption
Assumption: booking confirmation values are available server-side before the thank-you page renders, and the dev team can safely serialize only non-PHI fields into the page.
Open question: should renewals and initial certifications share one GA4 key event with product_type, or should GA4 also receive separate derived events for lifecycle audiences?