Context
When consent mode is enabled in Google Tag Manager, it often happens that some events are pushed to the dataLayer before the user even has a chance to accept cookies. Events commonly impacted by such scenarios are ‘view_item‘ and ‘view_item_list‘ events. Even if they accept, sometimes it’s tricky, or not possible to trigger the tags for these events after the cookies are accepted as the data associated with these events may be overwritten in the dataLayer.
But what if we can push those dataLayer events to the dataLayer again? That would give us all the information again, and we can trigger our tags with all the information.
Solution overview
To make this happen, we’ll need a way to read the dataLayer’s contents up to the point where the consent settings were updated. Many consent management platforms fire a dataLayer event. We can therefore read all dataLayer pushes up to that event, and send them again to the dataLayer.
Reading the datalayer
The dataLayer is a javascript object that’s on the page. This means we can access it by calling directly within the page. Here’s an example. Open the browser console, type ‘dataLayer
‘ and hit enter. This will show a list of events that were pushed to the dataLayer.
The next question is how to access individual events. Since the dataLayer is a list, we can simply type dataLayer[0]
which will give us the first event. Note that JavaScript lists are base 0, which means that the first element is 0, the second is 1, etc.
Reading each element before consent is updated
Our strategy to do this will be to loop over every element and push it to the dataLayer again. When we find the consent update, we’ll stop and exit the loop.
We’ll do this with a for loop. In my case, I’m using CookieYes which fires ‘cookie_consent_update’, therefore, you may need to adjust this event to match
One important note is that we need to read the dataLayer length before we start the loop, otherwise with each iteration, the length of the dataLayer becomes longer, leading to an infinite loop.
var dataLayerLength = dataLayer.length;
for(var i =0; i<dataLayerLength; i++){
if(dataLayer[i].event == "cookie_consent_update"){
break;
}
dataLayer.push(dataLayer[i]);
}
Removing gtm’s Unique Event ID
One important thing to note is that Google Tag Manager sets a unique event ID for each dataLayer event. If it has multiple events with the same event ID, it will only consider the first event registered with that ID and will ignore all subsequent events with that same ID.
Why is this important? If we push the same dataLayer event to the dataLayer without removing the gtm.uniqueEventID parameter, our new dataLayer pushes will be ignored. To do this, we’ll first copy the dataLayer event into a variable, remove the unique event ID, and then push the cleaned dataLayer event. Below is the code that we need to add
var dataLayerLength = dataLayer.length;
var dlEvent = {};
for(var i =0; i<dataLayerLength; i++){
if(dataLayer[i].event == "cookie_consent_update"){
break;
}
dlEvent = dataLayer[i];
delete dlEvent['gtm.uniqueEventId'];
dataLayer.push(dlEvent);
}
Pushing selected events
As discussed in the intro, we often would only need this for events like ‘view_item’, or ‘view_item_list’. In this section, we’ll make the necessary changes to the code to add the ability to only fire specific events again.
We’ll add a variable that holds the list of selected events, which we’ll then use in a filter to determine whether to fire the dataLayer event again or not.
var eventsToFire = ['view_item','test_event']
var dataLayerLength = dataLayer.length
var dlEvent = {};
for(var i =0; i<dataLayerLength; i++){
if(dataLayer[i].event == "cookie_consent_update" ){
break;
}
if(eventsToFire.includes(dataLayer[i].event)){
dlEvent = dataLayer[i];
delete dlEvent['gtm.uniqueEventId'];
dataLayer.push(dlEvent);
}
}
Putting it all into action
The code now needs to be put into a function and then placed within a custom HTML tag in GTM. We will then trigger the tag when the dataLayer event for the consent settings update is fired.
Below is the full tag. Feel free to adjust it to your needs.
Conclusion
In conclusion, we’ve discovered a nifty workaround to deal with the timing issues of dataLayer events and cookie consent in Google Tag Manager. By looping through the dataLayer and re-pushing events up until the consent update dataLayer event, we can ensure no data is lost. Pop this code into a custom HTML tag in GTM, and you’ll be capturing all the data you need, consent-permitting. Happy data gathering!
Leave a Reply