# How to Check and Debug the dataLayer in Chrome {#post-title}

[All Pixel Helper](/blog/#blog-all-pixel-helper)

By [B2B Gold](/about/#how-we-write) Published 25 September 2026

## How do you check the dataLayer in Chrome? {#how-do-you-check-the-datalayer-in-chrome}

Open Chrome’s DevTools console on the page and type `dataLayer`: it lists every object pushed so far, oldest first, and shows new pushes each time you run it again. To see which push fired which Google Tag Manager tag, use Tag Manager’s Preview mode, whose Data Layer tab shows the data after each event.

1. Open the page, then press **Control+Shift+J** (**Command+Option+J** on a Mac) to open DevTools’ **Console**.
2. Type `dataLayer` and press Enter.
3. Expand the array. Each numbered entry is one push, in the order it arrived.
4. Do what you’re testing on the page, such as adding to the cart or submitting a form, then run `dataLayer` again. New pushes appear at the end.

Two shortcuts help on busy pages. `dataLayer.filter((entry) => entry.event)` lists only the pushes that carry an event, and `dataLayer.at(-1)` shows the latest one.

> **Tip:** The console runs in the main page by default: its **JavaScript Context** drop-down starts at **top** ([Console reference](https://developer.chrome.com/docs/devtools/console/reference)). If the tags you’re checking run inside an iframe, pick that frame in the drop-down first.

## How do you read what the console shows? {#how-do-you-read-what-the-console-shows}

It’s a plain array of everything pushed on this page. Each object is one push; its `event` key is what Tag Manager’s triggers respond to, and the other keys are data that tags and variables can read. Google calls `event` a special data layer variable used to fire tags ([the data layer](https://developers.google.com/tag-platform/tag-manager/datalayer), last updated 22 July 2026, checked 25 September 2026).

What else you’ll see:

- **Tag Manager’s own entries.** Pushes named `gtm.js`, `gtm.dom` and `gtm.load` come from Tag Manager itself (see the FAQ below).
- **`gtag()` commands.** Google’s snippet defines `gtag()` as `dataLayer.push(arguments)` ([consent mode guide](https://developers.google.com/tag-platform/security/guides/consent)), so its commands show as `Arguments` lists such as `['config', 'G-…']` or `['consent', 'default', {…}]`. To check the consent commands properly, [check that Google Consent Mode is working](/blog/check-google-consent-mode/).
- **Nothing from the last page.** The array starts again on every page load. Google’s guide says values you need across pages must be declared in the data layer on each page.

A `dataLayer` that exists but is empty doesn’t prove Tag Manager is installed. Some debugging extensions create the array themselves, including the viewer described later in this guide, which adds an empty array to every page without a `dataLayer`. Look for a `gtm.js` entry, or for the container loading in the Network panel as a `gtm.js?id=GTM-…` request.

## How do you see which push fired which tag? {#how-do-you-see-which-push-fired-which-tag}

With Tag Manager’s Preview mode. Google’s steps start from the container you want to edit, and anyone with that access can share a preview link with you. Preview lists each event on the page and shows, for the one you select, whether each tag fired and what triggered it or didn’t ([preview and debug containers](https://support.google.com/tagmanager/answer/6107056)).

1. Open your container at tagmanager.google.com.
2. In the **Workspace** tab, click **Preview**. Tag Assistant opens in a new tab.
3. Enter the page’s address and click **Connect**. Your site opens in a new window (a new tab if you have Google’s Tag Assistant extension) and shows **Connected** in the bottom right.
4. Go back to the Tag Assistant tab and click **Continue**. The debug interface opens.
5. Do the action on your site, then select its event in Tag Assistant’s list of events.
6. Read the tabs for that event:
  - **Tags** separates the tags that fired on the event from those that didn’t.
  - **Variables** shows each variable’s resolved value at that event.
  - **Data Layer** shows what the page pushed for that event and the data layer’s state after it.

Preview is the only tool in this guide that shows why a tag didn’t fire. If you manage the container, start here.

## Why isn’t my dataLayer.push working? {#why-isnt-my-datalayerpush-working}

Usually because the push goes somewhere Tag Manager isn’t listening, arrives too late, or carries no `event`. Check the console first: if the push isn’t in `dataLayer`, the problem is on the page; if it is, the problem is in the container’s triggers or variables, and Preview will show which.

| Cause | Sign | Fix |
| --- | --- | --- |
| The array is reassigned, as in `dataLayer = [{…}]` | Earlier entries disappear from the console | Initialise the array once, with Google’s line below the table, and use `.push()` from then on |
| Wrong case: `datalayer.push(…)` | An error in the console, or pushes Tag Manager never reads | Write `dataLayer`: the name is case-sensitive |
| The snippet renames the data layer | Pushes to `dataLayer` never reach the container | Push to the name the snippet sets, or remove the rename |
| Values pushed below the container snippet | Variables are empty on the first events and fill in later | Declare values needed at load above the container code |
| No `event` key | The data sits in the array but no custom event trigger fires | Push the data with an event, such as `{ event: "sign_up", method: "email" }` |
| An earlier ecommerce push lingers | Items or values from one event turn up in the next | Push `{ ecommerce: null }` before each ecommerce event |
| The push runs inside a Shopify custom pixel | Nothing new in the storefront’s `dataLayer` | Pick the pixel’s frame in the console; the pushes live in its sandbox |

Google’s initialisation line, placed high in the page before the container snippet, is `window.dataLayer = window.dataLayer || [];`. It keeps whatever is already in the array instead of replacing it.

Sources: Google’s [data layer guide](https://developers.google.com/tag-platform/tag-manager/datalayer) for the first four rows and the `event` key, and its [GA4 ecommerce guide](https://developers.google.com/analytics/devguides/collection/ga4/ecommerce?client_type=gtm) (last updated 19 August 2026), whose examples clear the previous ecommerce object before each push. On the last row, Shopify’s [custom pixel testing guide](https://help.shopify.com/en/manual/promoting-marketing/pixels/custom-pixels/testing) says Chrome can show one iframe’s console logs, and its [Tag Manager custom pixel tutorial](https://help.shopify.com/en/manual/promoting-marketing/pixels/custom-pixels/gtm-tutorial) pushes Shopify’s events to `window.dataLayer` from inside the pixel. What that set-up can and can’t do is in [Google Tag Manager in a custom pixel](/blog/shopify-app-pixels-vs-custom-pixels/#can-you-use-google-tag-manager-in-a-custom-pixel).

## How do you turn a dataLayer value into a GTM variable? {#how-do-you-turn-a-datalayer-value-into-a-gtm-variable}

With a Data Layer Variable whose name is the dotted path to the value. Google’s help says **Version 2** of the variable interprets dots as nested values, so `a.b.c` reads `{a: {b: {c: "value"}}}` ([user-defined variable types](https://support.google.com/tagmanager/answer/7683362)).

Take a purchase push like this one, which clears the previous ecommerce object first, as Google’s examples do:

```
dataLayer.push({ ecommerce: null });  // Clear the previous ecommerce object
dataLayer.push({
  event: "purchase",
  ecommerce: {
    transaction_id: "T_12345",
    value: 59.98,
    currency: "EUR",
    items: [
      { item_id: "SKU_12345", item_name: "Example T-shirt", price: 29.99, quantity: 2 }
    ]
  }
});
```

The transaction ID’s path is `ecommerce.transaction_id` and the value’s is `ecommerce.value`. For a value inside the `items` array, a numeric index is widely used: `ecommerce.items.0.item_id` for the first item’s ID. Google’s help documents the dots, not array indexes, so confirm the result in Preview before you rely on it.

1. In Tag Manager, click **Variables** in the left navigation.
2. In the **User-Defined Variables** section, click **New**.
3. Click **Variable Configuration** and choose **Data Layer Variable**.
4. Enter the path, such as `ecommerce.transaction_id`, as the data layer variable name.
5. Check that **Version 2** is selected.
6. Give the variable a descriptive name and click **Save**.
7. In Preview, select the `purchase` event and find the variable on the **Variables** tab. Its resolved value should be `T_12345`.

## Can you debug Tag Manager without Preview mode? {#can-you-debug-tag-manager-without-preview-mode}

Partly. When you can’t open the container, or Preview won’t connect, the console shows what the page pushed and Chrome’s Network panel shows what its tags sent, such as GA4’s requests to an address ending in `/g/collect`. Neither shows triggers or why a tag didn’t fire.

That’s enough to answer “did the page push the right data?” and “did a request go out?”. It isn’t enough to answer “why didn’t this tag fire?”. For that you need Preview: ask someone who manages the container to send a link from Tag Assistant’s **Share** option. If Preview can’t find your tag, see [Google tag not detected](/blog/google-tag-not-detected/). To read each vendor’s requests on the page, see how to [check whether a pixel is working](/blog/check-if-pixel-is-working/).

## How do you see each push as a tree and copy its path? {#how-do-you-see-each-push-as-a-tree-and-copy-its-path}

A long dot path is easy to mistype, so a viewer that copies it for you saves a round trip through Preview.

[All Pixel Helper](/chrome/all-pixel-helper/), which we build, is a free Chrome extension with a **dataLayer** tab: a **Push Timeline** of the pushes to `window.dataLayer`, newest first. Open a push as a tree, hover a value and click **Path** to copy its dot-notation path (the tooltip reads “Copy GTM Path: …”), ready for a Data Layer Variable; **Val** copies a value and **JSON** an object. Array items come out with numeric indexes, such as `ecommerce.items.0.item_id`, so check those in Preview as above. Its limits: it watches only a data layer named `dataLayer`, so a renamed one doesn’t show; `gtag()` calls appear as rows named “push” with numbered keys (`0`, `1`, `2`), so their paths are meaningless; it shows at most 100 pushes a second per frame; and like the console, it shows what was pushed, not which tags fired. It’s the viewer mentioned earlier that adds an empty `window.dataLayer` to every page without one, and it wraps `dataLayer.push` to copy each push. The extension itself sends nothing anywhere.

## What should an ecommerce push contain? {#what-should-an-ecommerce-push-contain}

For a GA4 purchase: the event name `purchase`, a `transaction_id`, a numeric `value` with its `currency`, and an `items` array in which each item has an `item_id` or an `item_name`. Google marks `transaction_id` and `items` as required, and says currency is required whenever you set a value “for revenue metrics to be computed accurately” ([GA4 events reference](https://developers.google.com/analytics/devguides/collection/ga4/reference/events)).

The example above has all of them. Other ecommerce events follow the same shape with their own required fields, listed in the same reference. How Shopify stores send the purchase to GA4 is a different path, covered in [how Shopify sends purchases to GA4](/blog/ga4-shopify-purchases/#how-does-shopify-send-purchases-to-ga4).

## Frequently asked questions {#frequently-asked-questions}

### Why is `dataLayer` undefined? {#why-is-datalayer-undefined}

Because nothing on the page created it: there’s no Tag Manager or Google tag, the data layer has another name, or the console is pointed at a different frame. Check the Network panel for the container loading, and the console’s **JavaScript Context** drop-down. The opposite can mislead too: if a debugging extension created the array, `dataLayer` exists but holds nothing from the site.

### Does Shopify have a dataLayer? {#does-shopify-have-a-datalayer}

Not by default. Your theme or an app has to push to one, and a theme’s layout applies only to pages outside checkout ([Shopify layouts](https://shopify.dev/docs/storefronts/themes/architecture/layouts)). A custom pixel’s pushes go to a `dataLayer` inside the pixel’s own frame, not the storefront page’s.

### What are gtm.js, gtm.dom and gtm.load? {#what-are-gtmjs-gtmdom-and-gtmload}

Tag Manager’s own events. Google’s help names them Container Load (`gtm.js`, as soon as possible after the page starts loading), DOM Ready (`gtm.dom`, once the page’s HTML is ready to be parsed) and Window Load (`gtm.load`, once all initial content has loaded) ([Scroll Depth trigger](https://support.google.com/tagmanager/answer/7679218)). The container snippet pushes `gtm.js` itself, so they appear on every page with a container, whether or not the site pushes anything.

[All Pixel Helper - Tag, dataLayer & Consent Debugger](/chrome/all-pixel-helper/)

All Pixel Helper is a free Chrome extension that lists and decodes the requests a web page sends to 40 ad and analytics platforms, including Meta, TikTok, GA4, Google Tag Manager and Shopify, and marks each one delivered, failed or blocked. It also shows every dataLayer push, with paths you can copy into Tag Manager, and the consent signals on Google, Meta, Microsoft and TikTok requests.

[Add to Chrome](https://chromewebstore.google.com/detail/all-pixel-helper-tag-data/bdedmcfjebcoemocjajpohkbnohbfeld?utm_source=b2bgold.app&utm_medium=referral&utm_campaign=blog&utm_content=blog/check-datalayer-in-chrome&utm_term=post-cta) [Plans and pricing](/chrome/all-pixel-helper/#pricing)

Need help with All Pixel Helper? Email [chrome@afixer.app](mailto:chrome@afixer.app).

## More on All Pixel Helper {#related-heading}

- 25 September 2026 **[Google Tag Not Detected? Why Tag Assistant Misses It](/blog/google-tag-not-detected/)** Google says your tag isn't detected or Tag Assistant won't connect? Check the page's requests, Shopify custom pixels, consent, ad blockers and CSP, in order.
- 25 September 2026 **[Pixels Blocked by an Ad Blocker or CSP? How to Tell](/blog/pixels-blocked-ad-blocker-csp/)** Tell an ad blocker from a Content Security Policy or a consent tool when tags go missing: ERR_BLOCKED_BY_CLIENT, CSP errors in the Console, and what to fix.
- 25 September 2026 **[How to Check Google Consent Mode v2 Is Working](/blog/check-google-consent-mode/)** Check Google Consent Mode v2 step by step: Tag Assistant's Consent tab, gcs and gcd on Google's requests, Google Ads Diagnostics and Shopify's privacy settings.
