Home / Guides

The shop whose dataLayer is empty

You open the inspector on a working shop and nothing arrives. The events are real, they fired, and they are not in window.dataLayer. Four platforms route them somewhere no extension can read, and each has a different place to read them instead.

The symptom is disorienting because everything else looks right. The shop takes orders, the reports fill up, GA4 shows purchases. You open a dataLayer inspector on the same page to check what the checkout pushes, and the list is empty. Not wrong — empty.

Almost every answer to this assumes a mistake: the container is missing, the snippet is above the push, the layer is named something else. Sometimes it is one of those. On four widely-used platforms it is none of them, and no amount of looking at window.dataLayer will help, because that is not where the events are.

The dataLayer is not the only data layer

An extension reading dataLayer is reading one array on the top window. That convention belongs to GTM. Other stacks never adopted it:

The events panel with no dataLayer events, above a notice saying the site runs Shopify Web Pixels, that its events go through a sandboxed pixel frame rather than the page dataLayer, and that the hits are still readable in Network.
An empty list that says why it is empty. The distinction between "nothing happened" and "it happened somewhere you cannot watch" is the whole guide, and it is worth the panel spending four lines on.

A panel that shows an empty list on a Tealium site is not reporting the truth. The truth is that the events exist and travel by another road. Tag Master names the foreign layer it found and says what it sends — Tealium, through utag.view() and utag.link() — rather than leaving a blank list to interpret. For Adobe Launch it goes one step further and reads the rules that fired, through the monitor hook Adobe publishes for exactly that purpose.

Shopify is the hardest case, and the most common

Shopify moved its tracking into Web Pixels: small scripts that run inside a sandboxed frame with their own event bus and their own dataLayer. product_added_to_cart, checkout_started and checkout_completed are dispatched in there. They do not reach the top window, and nothing running in the page can subscribe to them — not this extension, not any other. That is the sandbox working as designed.

Checkout makes it worse, because Shopify’s checkout has always been a separate context. So the one event most implementations care about most, purchase, is also the one furthest out of reach of anything reading the page.

The exception is a store running Elevar or a similar relay, which republishes the sandbox’s events onto the page as dl_purchase, dl_add_to_cart and the rest. If those names are showing up, the layer is being relayed and you are reading a copy — a good copy, but under a different spelling.

Where to read them instead

On every one of these platforms the events still turn into network requests, and requests cannot be sandboxed away from a debugger that watches the network. What GA4 received is in the /g/collect hit; what Meta received is in the /tr call. The push is hidden; the consequence is not.

So the procedure inverts. Instead of reading the push and checking that the tag matched it, you read the hit and work backwards to whether it carried what it should have: the right event name, a value, a currency, a transaction ID. Reading a GA4 hit parameter by parameter is the whole skill on these shops, and listing what the page sent is how you find out which platforms are involved before you start.

Before you go looking for a bug

  1. Confirm which layer the site actually has. window.utag, window._satellite, window.adobeDataLayer, window.Shopify — one line in the console each, and the answer changes what you do next.
  2. If it is Shopify without a relay, stop looking for pushes. Go to the network.
  3. If it is Tealium or Launch, the events are in the vendor’s own debug console, which can be switched on for the tab you are already using.
  4. Only then, if the site really is a GTM site with a real dataLayer, treat an empty list as a bug worth chasing.

An empty inspector is a fact about where the events are, not a verdict on whether they exist. The shops above are the reason to check which of the two you are looking at.

Questions

Why is my Shopify dataLayer empty?

Because Shopify’s Web Pixels run inside a sandboxed frame with their own dataLayer. product_added_to_cart and checkout_completed never reach the top window, so no extension running in the page can see them — this one included. The requests they produce are still on the network.

Is checkout tracking really invisible?

The pushes are. Shopify’s checkout has always run in its own context, and Web Pixels formalised that. What the pixels send out is ordinary network traffic and is readable in full, which is why the answer on a Shopify store is to work from the hits rather than the layer.

What about Tealium and Adobe?

Neither uses an array. Tealium sends events through utag.link() and utag.view(), Adobe Launch through _satellite.track(). Those are function calls, so no list of dataLayer names reaches them. Launch is the exception with a documented monitor hook, and the rules it fired can be read through it.

Does an empty dataLayer mean tracking is broken?

No, and treating it that way is the expensive mistake. A shop can send a perfectly correct purchase to five platforms with nothing in window.dataLayer at all. Check the network before concluding anything about the layer.

Doing this in the panel →

The rest of this group: Shops and their data layers

More in Shops and their data layers

Try it on your own site

Tag Master is free, needs no account, and collects no data.

Add to Chrome — Free