Most tracking problems start before anyone opens Tag Manager. Nobody wrote down what the website should send, so developers guessed, tags scraped the page, and every report since has been a little different from the last.
A dataLayer specification fixes that. It's the agreement between the business, the developers and whoever runs your tags about exactly what the site says, and when.
What's in the template.
- Events: one row per event, with the exact moment it fires, who pushes it, its parameters, an example push, whether it's a key event, and the consent it needs.
- Parameters: one definition for every value, with its type, format, an example, and whether it could be personal data.
- GA4 item fields: how your products, listings or services fill GA4's item fields, from
item_idtoprice. - Naming rules: the conventions that keep data clean, including GA4's limits on names and values.
- Test log: a record of each event tested, with consent accepted and refused, on desktop and mobile.
Grey rows are worked examples for page_view, view_item_list, view_item, form_view, generate_lead and purchase. Yellow cells are for you to fill in, and the dropdowns keep values consistent.
How to fill it in.
- Start from the questions. Your measurement plan says what the business needs to know. Every event should answer one of those questions.
- List the events. Use GA4's recommended names where one fits. For each, write the exact trigger: "the server accepts the form", not "the form is submitted".
- Define the parameters once. If two events carry a form type, it's the same parameter with the same name and the same allowed values.
- Agree it. Developers, marketing and whoever owns consent sign it off before anything is built.
- Test against it. Each event goes in the test log as it's built, including what happens when consent is refused. The guide to testing Consent Mode v2 covers that part.
An example row.
Here's how a lead looks when the website pushes it itself:
dataLayer.push({
event: "generate_lead",
form_type: "valuation",
form_id: "valuation-main",
lead_id: "L-10293",
value: 0,
currency: "GBP",
event_id: "9f2c1a"
});
It fires when the server accepts the form, not when the button is clicked. It carries a reference, not a name or email address. Its value is one the business agreed, or zero. And the event_id lets ad platforms count a browser copy and a server copy once.
Mistakes the template is designed to stop.
- Enquiries sent as purchases. A lead isn't a sale. Recording it as one breaks revenue reports and misleads ad platforms bidding on it.
- Tags that scrape the page. Reading button text or waiting for a thank-you message works until the next redesign. If the site pushes the event, it keeps working.
- The same thing with three names.
formType,form_typeandForm Typebecome three columns in your reports. - Price times quantity in the price field. GA4 expects the unit price and multiplies it for you.
- Personal data in the dataLayer. Names, email addresses and free-text fields don't belong there. Everything on the page can read the dataLayer.
Where it fits.
The dataLayer is the second of the five layers in a good tracking architecture, and everything above it depends on getting it right. As another article here puts it: your dataLayer decides which questions your business can answer.
Download the template (Excel). It's free to use and adapt.