Data & Tracking
Data layer: what it is and how to set it up for GTM and GA4
Copy for AI
A data layer is a JavaScript object on your website in which you lay out structured information for Google Tag Manager and the Google tag. Instead of GTM having to guess what happens on a page by looking at buttons and texts, your website tells it directly: “a quote request was submitted, for service X, via form Y”. That makes your tracking more reliable, easier to test and less sensitive to every change to your site. In this article you will read how a data layer works, how to set it up and which mistakes to avoid.
What is a data layer?
In its documentation for Tag Manager, Google describes this object as “an object used by Google Tag Manager and gtag.js to pass information to tags”. Your website puts data and events into that object; GTM reads them via variables and uses them in triggers and tags.
In concrete terms, it is a list (array) named dataLayer. Every time something happens, you add an object to it with dataLayer.push():
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'lead_submit',
'form_id': 'quote',
'lead_type': 'quote_request',
'service': 'tracking-audit'
});
The event key has a special role: GTM uses it to fire tags. The other keys become variables that you can pass on to GA4, Google Ads or Meta.
Why use a data layer?
Without such a layer, you build tracking on what GTM can see on the page: a click on a button with a certain text, a CSS class, a thank-you page URL. That works until someone changes the button text, replaces the form with a new plugin or removes the thank-you page. Then your measurement stops, often without anyone noticing.
| Tracking on the page (DOM) | Tracking via the data layer | |
|---|---|---|
| Source of the data | Buttons, texts, CSS classes, URLs | Explicit pushes from the website |
| Sensitive to a redesign | High | Low, as long as the push stays |
| Extra information | Only what is visible | Internal values too: service, lead type, order value |
| Testable and documentable | Difficult | Yes, it is a fixed contract |
| Work for developers | None | One-off, plus maintenance |
At Suivo, a form update silently stopped lead measurement without any error message. The solution was a robust form listener and a clean layer of events, so that the next update does not break the measurement again. At Kaizo, the booked demo got its own event in the data layer, so that GA4, Google Ads and Meta see exactly the same conversion.
Setting up a data layer in 6 steps
1. Write a measurement plan
First decide which actions you want to measure and which information belongs with them. For a B2B site that is often: a quote request, a demo booking, a contact form, a download, a click on a phone number. For each event you record the name and the parameters, for example lead_submit with form_id, lead_type and service. Where possible, use the recommended GA4 events, so your reports and Google Ads can work with them straight away.
2. Write a specification for your developer
For each event, document when the push must happen (only after a successful submission, not on the button click), which keys it contains and which values are allowed. If you work with a CMS or CRM forms, such as WordPress with Gravity Forms, HubSpot or forms linked to Teamleader or Odoo, also note where the push technically comes from.
3. Declare the data layer before the GTM snippet
Google recommends declaring the object before Tag Manager loads, with window.dataLayer = window.dataLayer || [];. That way you never overwrite data that was already in place. So never write dataLayer = [...] further down in your code: you would wipe everything that was in it before.
4. Have the website push the events
The developer adds the pushes at the agreed moments. For e-commerce, follow the structure of GA4 e-commerce. There, Google first clears the previous e-commerce object, so old product data does not piggyback on the next event:
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
'event': 'purchase',
'ecommerce': {
'transaction_id': 'T_12345',
'value': 72.05,
'currency': 'EUR',
'items': [{ 'item_id': 'SKU_1', 'item_name': 'Product', 'price': 72.05, 'quantity': 1 }]
}
});
For a purchase, transaction_id, value, currency and items are the fields that always belong in it. A missing currency is a classic: revenue then arrives incorrectly or not at all.
5. Build variables and triggers in Google Tag Manager
In GTM, create a variable of the “Data Layer Variable” type for each key (for example form_id), and for each event a trigger of the “Custom Event” type with exactly the same name as in the push. Then connect them to your tags: a GA4 event, a Google Ads conversion, a Meta event. Read more about the container itself in our article on Google Tag Manager.
6. Test and document
Open preview mode and check in Google Tag Assistant, on the Data Layer tab, whether the push arrives at the right moment and with the right values. For a quick look, you can also use your browser’s console: type dataLayer and you see the full list. In our projects we record the result in a shared document, so whoever works on the site later knows which pushes must not be removed.
The key rules for a clean data layer
- Case-sensitive. The object is called
dataLayer, notdatalayer. Your keys and event names must also match exactly what GTM expects. - Use quotes around keys. Google recommends
{'variable_name': 'value'}. - Per page. According to Google, such a variable only persists as long as the visitor stays on the current page. If you need a value on every page, push it again on every page load.
- One data layer per page. You can rename the object, but Google supports only one
dataLayerobject per page. - Consistent names. Choose one naming convention (for example lowercase with underscores) and stick to it across all events.
No personal data in your data layer to GA4
It is tempting to push a lead’s email address or phone number along. For GA4 that is not allowed: Google’s policy on personal data states that you must not send data to Google that it could recognise as personally identifiable information, including email addresses and phone numbers. If you want to use that data for enhanced conversions in Google Ads, that happens via the dedicated, hashed route, and only with consent. Also take consent into account: without consent your tags may not pass the data on with cookies, even if it is ready in the object. More on that in consent mode v2 for Google Ads.
Common mistakes with the data layer
- The push happens on the click, not after the submission. Every failed or half-completed form then counts as a lead.
- The object is overwritten after the GTM snippet. A
dataLayer = []in a theme or plugin wipes everything that was in place before. - Different names in the push than in GTM.
leadSubmitin the code,lead_submitin the trigger: the tag never fires. - Old e-commerce data that lingers. Without
ecommerce: null, apurchasecan carry along products from a previous step. - Single-page apps without virtual page views. A site in React or Vue does not load new pages, so you have to push an event yourself on every route change.
Read about similar problems on the GA4 side in common mistakes in Google Analytics tracking.
Frequently asked questions
What is the difference between a data layer and Google Tag Manager?
The data layer is the information your website lays out. Google Tag Manager is the tool that reads that information and decides which tags fire and what they pass on. The object also works without GTM, with the Google tag (gtag.js), but only reaches its full potential with GTM.
Do I need a developer for a data layer?
For the pushes from your website, usually yes, or a plugin that generates them for your CMS or webshop. A marketer or tracking specialist can set up the variables, triggers and tags in GTM themselves.
How do I view the data layer in Chrome?
Open the developer tools, go to the console and type dataLayer. You then see all pushes on that page. GTM preview mode gives a clearer overview, with a Data Layer tab that shows per moment what came in.
What is a datalayer.push?
dataLayer.push() is the function you use to add a new object to the data layer. If that object contains an event key, GTM can fire a trigger on it.
Does the data layer have anything to do with a data warehouse?
No. In data engineering, people also talk about “data layers” (for example bronze, silver and gold in a data warehouse). That is a different concept. In marketing tracking, we mean the dataLayer object on your website.
Want a data layer set up for you?
A well-designed dataLayer is the foundation under your GA4, Google Ads, Meta and server-side tagging. Our tracking specialist writes the measurement plan and the specification for your developer, builds the container and tests every event. If you first want to know where your current setup stands, start with a tracking audit. Read more about the bigger picture in conversion tracking, or get in touch.
Free website scan
Enter your website and get an automatic scan within minutes, with concrete technical and SEO improvements. No sales pitch.
We only use your details for your scan. No spam, unsubscribe anytime.