One of Google Tag Manager’s oldest and most reliable features is that it freezes the state of Data Layer variables to the moment when the trigger event occurred. Thus, any tags firing on this trigger (and any variables resolved on this trigger event) will always have access to the same value of each Data Layer variable.
However, there are situations where this is not a good thing. One is tag sequencing, and the other is a scenario where you want to run some custom code that should access the latest value of the Data Layer variable at a moment in time after the tag has already fired. Read on for an example!
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 98: Access the latest value of a Data Layer variable
For example, let’s say your site has a custom event listener built to detect when the user is about to leave a page (using the beforeunload
custom event). However, you only want to send that event if the user is logged out, for some obscure reason.
This is what your first attempt might look like. It’s a Custom HTML tag set to fire when the page is first loaded with the All Pages trigger.
<script>
(function() {
window.addEventListener('beforeunload', function() {
if ({{DLV - loginStatus}} === 'logged-out') {
window.dataLayer.push({
event: 'userLeavesPages'
});
}
});
})();
</script>
Now, when the Custom HTML tag fires, the beforeunload
listener is created, and the {{DLV - loginStatus}} variable is resolved to whatever value it had when the tag fired.
Then, when the user is about to leave the page by closing the browser or clicking a link, the beforeunload
callback is executed, and it checks if this original state of loginStatus
is “logged-out”, in which case it runs the dataLayer.push()
.
Do you see the problem here? The beforeunload
event is not fired until the user tries to leave the page, but the {{DLV - loginStatus}} is resolved to whatever value it had when the tag itself was initially run. If the loginStatus
changes while the user is on the page, it wouldn’t make a difference. The initial value is what’s used in the if...
condition, meaning you’ll risk losing valid hits because of that.
So we need a mechanism that fetches the value of the Data Layer variable when the relevant code is run. We want the if...
condition to evaluate against what the value of loginStatus
is at the time of the beforeunload
event and not when the tag is first run.
For this, we use a JavaScript method that is built into Google Tag Manager and allows us to do exactly this.
window.google_tag_manager[{{Container ID}}].dataLayer.get('variableNameHere');
Remember to enable the Container ID built-in variable for this.
This method polls GTM’s internal data model and fetches the latest value of the variableNameHere
Data Layer variable. So, to modify the original example, here’s what you end up with:
<script>
(function() {
window.addEventListener('beforeunload', function() {
if (window.google_tag_manager[{{Container ID}}].dataLayer.get('loginStatus') === 'logged-out') {
window.dataLayer.push({
event: 'userLeavesPage'
});
}
});
})();
</script>
Now the if...
condition checks what the latest value of loginStatus
is, and it will work nicely if the status has changed while the user is on the current page.
It’s a simple trick, but can come in handy when working with GTM’s idiosyncractic way of freezing the variable state for the duration of each trigger event.