Here’s a tip on how to avoid a horrible, horrible mistake with Google Tag Manager.
The Simmer Newsletter
Follow this link to subscribe to the Simmer Newsletter! Stay up-to-date with the latest content from Simo Ahava and the Simmer online course platform.
Tip 7: Always use .push() with dataLayer
When you assign a value to a variable using the equals ( = ) sign, you are actually reallocating the variable to a new value, and the garbage collection system of the runtime environment sweeps the previous value to bit heaven.
Let’s put it simply: if you redefine dataLayer
after the GTM container snippet, you will break GTM’s proprietary functions. No, I’m not trying to be dramatic, it’s the truth. You cause havoc because GTM modifies the native push()
method that all Arrays have, adding stuff of little importance such as a listener which fires tags when an ‘event’ key is pushed!.
By redefining dataLayer
your tags will no longer fire. Oops!
But hey, we’re often instructed to use variable assignment when creating dataLayer
before the container snippet. Right? Well, yes, that’s what we’re instructed to do but that’s not necessarily the best practice. Having just one declaration there works like a charm, but what about:
<script>
dataLayer = [{
'businessCriticalVar' : 'businessCriticalVal'
}];
</script>
... some other code ...
<script>
dataLayer = [{
'anotherCriticalVar' : 'anotherCriticalVal'
}];
</script>
</head>
<body>
<!-- GTM Container Snippet -->
Well, you might have guessed it. The second assignment overwrites the first one, and dataLayer
only has anotherCriticalVar available for the benefit of your tags.
So how to avoid this?
Simple: use only push()
when interacting with dataLayer
. That way you’ll never overwrite anything in the Array, you’ll just add new stuff to the end.
In GTM tags (Custom HTML, for example), you can just go ahead and use dataLayer.push()
, since you can be 100 % sure that dataLayer
is an Array with a push()
function (the container snippet takes care of this for you). But when you’re working on the page template, where it’s not necessarily a given that dataLayer
has been defined as an Array, always use the following syntax to safeguard against problems:
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'someVar' : 'someVal'
});
The first line basically checks if a global variable called dataLayer
has already been declared. If it has, it’s left alone and execution proceeds to the push()
block. If, however, dataLayer
has NOT been defined, the first line then assigns a new, empty Array to it. This ensures that the following push()
will always work.
So here’s the recap:
-
When working on the page template, always check whether or not
dataLayer
has been defined, and initialize it as a new Array if necessary -
Always, ALWAYS, use
push()
when interacting withdataLayer
DISCLAIMER:
The window.dataLayer = window.dataLayer || [];
fails if dataLayer
HAS been defined but not as an Array. This is probably quite rare, but you should be aware of what variable has been assigned to GTM by looking at the container snippet’s self-invoking function parameters.