What you will learn
- Explain what a data layer is and why it exists
- Write a dataLayer push for an event and for page information
- Name the common mistakes: timing, naming and stale values
- Decide who owns the data layer's specification
Tracking tags need facts about the page: what the product is, how much it costs, who is logged in, what the visitor just did. There are two ways to get them. One is to scrape the page, reading text out of elements with selectors. The other is to have the page say what is happening. The second is a data layer.
What it is
A data layer is a JavaScript array, usually called dataLayer, that the page fills with plain objects. A tag manager watches the array and reads from it.
window.dataLayer = window.dataLayer || [];
// information about the page, pushed as it loads
window.dataLayer.push({
page_type: 'product',
user_status: 'logged_in',
});
// something the visitor did
window.dataLayer.push({
event: 'add_to_cart',
ecommerce: {
currency: 'EUR',
value: 29.9,
items: [{ item_id: 'SKU-123', item_name: 'Desk lamp', price: 29.9, quantity: 1 }],
},
});
The first line creates the array if the tag manager has not yet loaded, so the page can start pushing straight away. A push with an event key is special: it tells the tag manager that something happened, and any trigger set to listen for add_to_cart fires.
Why not scrape the page?
Scraping reads .price-box > span.amount and hopes. The day a designer renames a class, the tag silently reports nothing. A data layer moves the responsibility to where the knowledge is: the developer who builds the page knows the price and the product id, and publishes them under agreed names. The tags no longer depend on markup.
It also separates jobs. Developers maintain the data layer. Marketers and analysts change tags in the tag manager without a release.
Good habits
- Write a specification. A document (or a shared sheet) listing each event, its name and its parameters, with an example. It is the contract between developers, analysts and anyone who tests.
- Name things consistently. Pick a convention (
snake_case, as inadd_to_cart) and keep it. If you send events to Google Analytics 4, use its recommended event and parameter names where one exists, so the standard reports work. - Push values, not decisions. Publish "price 29.9" and let the tag manager decide what to do with it. Putting tag logic in site code means a release for every change.
- Push at the right moment. Values must exist before the tag that needs them fires. Page-level information belongs before the tag manager's container loads, or must be followed by an event that triggers the tags.
- Clear the previous value. Data layer values persist and are merged, so an old
ecommerceobject can leak into the next event. Google's guidance for e-commerce events is to push{ ecommerce: null }first, then the new object.
window.dataLayer.push({ ecommerce: null }); // clear the previous ecommerce object
window.dataLayer.push({ event: 'purchase', ecommerce: { transaction_id: 'T-1001', value: 59.8, currency: 'EUR', items: [] } });
- Keep personal data out. Do not push e-mail addresses, names or anything that identifies a person unless you have a clear legal basis and the tags that receive it are meant to. A hashed identifier or an internal id is usually enough.
The mistakes behind most broken tracking
| Symptom | Common cause |
|---|---|
| An event never reaches your reports | The push has no event key, the name differs from the trigger's (case matters), or it runs before the container loads and nothing listens |
| A value is blank in the tag | The variable path is wrong (ecommerce.items against items), or the value is pushed after the tag fired |
| Events are counted twice | The same push runs twice (a framework re-rendering a component), or two triggers fire the same tag |
| A new page shows the last page's value | A single-page app never resets values, so the old ones are merged into the new push |
Testing
Use your tag manager's preview mode: it lists every push in order, shows the data layer's state at that moment and which tags fired. Test each event from the specification, on a staging copy first, and keep the results with the specification. When something breaks in a year, you will know what "working" looked like.
Glossary
- Data layer
- A JavaScript array on the page where information about the page and its events is stored for tags to read.
- Tag manager
- A tool (such as Google Tag Manager) that loads and fires tracking tags according to rules.
- Event
- A named occurrence pushed to the data layer, such as add_to_cart.
- Trigger
- A rule in the tag manager that fires a tag, often when a given event name arrives.
- Data layer variable
- A tag manager setting that reads a value from the data layer.
Frequently asked questions
Do I need a data layer if I use a tag manager?
You can get by without one by scraping the page, but it breaks whenever the page changes. A data layer is the stable contract between the site and the tags.
Is the data layer only for Google Tag Manager?
The name and the dataLayer.push pattern come from Google Tag Manager, but the idea (a structured, agreed set of values the page publishes) applies to any tag manager or tracking setup.
Next steps
- List the events and values your reports need, and write them down as a specification
- Test each push in your tag manager's preview mode
References
From Grokem: https://www.grokem.com/data/data-analytics/tag-management/data-layer-explained




