
June 5, 2020
Data Layer Variable in GTM: What, Why, and Where?
Updated: June 5th, 2020
If you have done anything with Google Tag Manager, you probably already know three key concepts: tags, triggers, and variables. But, actually, you should know there is one more key ingredient, the Data Layer. Google Tag Manager walks hand in hand with the Data Layer which ensures maximum flexibility, portability, and ease of implementation. Without it, there would be no variables and no triggers in GTM, therefore no tags would be fired. It is what keeps your tag management running properly.
Unfortunately, I’m not going to dive into what the Data Layer is because that’s a totally another story. In today’s blog post, I’ll take a look at what the Data Layer Variable is.
If you have no clue what Data Layer is, read this guide first and then come back to this article.
The context
Before we dive in, let’s quickly remember how the Data Layer (DL) works. DL is a virtual layer of a website where useful information is stored, e.g. user ID, Text of a Clicked Button, Order Total, etc. This data can be later transferred to other tools like Google Analytics, Mixpanel, Google Ads, etc.
In fact, Google Tag Manager already supports a bunch of default built-in variables. You can find a full list of them by going to Variables > Configure.
After you enable these variables, they’ll appear in GTM Preview and Debug mode’s Variables Tab.
These data points can later be used in trigger conditions, tags, even other variables (e.g. Lookup or Regex Tables). And that’s awesome! But what if we want to have some custom variables? For example, blog post author’s name, user’s registration country, etc.?
That’s where the Data Layer Variables come in handy.
What is a Data Layer Variable?
Data Layer Variable enables you to fetch a value from the Data Layer and turn it into a variable (which can be used in Tags, Trigger, and other variables). But first, let’s take a look at how the data is stored in the Data Layer.
Enable the GTM Preview and Debug mode and go to the Data Layer tab. In the screenshot below I am viewing my blog’s data, yours might look different.
Looks like I have some interesting data there: pagePostType, pagePostType2, pageCategory, pagePostAuthor. My blog is running on WordPress and I’m using DuracellTomi’s GTM Plugin which pushes this data to the Data Layer every time page loads.
If you want to get even more custom information, ask a developer to add it to the Data Layer with the help of dataLayer.push.
Anyway, let’s go back to the example. As you can see in the screenshot above, there’s some interesting data I could employ in my tags and triggers. Unfortunately, if I navigate to the Variables tab of the Preview and Debug Console, those variables aren’t there. Why?
By default, Google Tag Manager does not recognize custom data in the Data Layer thus you cannot use it as variables unless you use the Data Layer Variable. In order to create this variable, you’ll need to specify the Data Layer key whose value you want to retrieve. When the Variable is resolved, it will return whatever was most recently pushed into the key. Easy as that!
If I wanted to fetch pageCategory value, I’d just need to set the pageCategory key in variable’s settings. Let me show you how it works in action.
Let’s create a Data Layer Variable
In my previous example, there were 4 custom keys and values in the Data Layer:
- Key: pagePostType, value: post
- Key: pagePostType2, value: single-post
- Key: pageCategory, value: google-tag-manager-tips
- Key: pagePostAuthor, value: Julius Fedorovicius
With help of Data Layer Variable, I can easily retrieve those values and re-use them in other tags, triggers, or variables.
Say, you want to send a Google Analytics event when someone leaves a comment. With every event, you also want to push the article author’s full name. This way you’ll see which authors drive the highest reader engagement.
In this example, I will not go into details on how to create a tag, as I will only demonstrate how to pull the data from the Data Layer and turn it into a variable (within Google Tag Manager).
In Google Tag Manager account, you should go to Variables and create a new one with the following settings (dlv stands for data layer variable):
That’s it! Save this variable, refresh Preview and Debug (P&D) mode, and refresh the website you’re working on. You should then see your newly created variable in the Variables tab of the P&D console.
Data Layer version
Another setting available in the Data Layer Variable is Version. When you select the Version, you’re instructing GTM to treat the values in the data model in two different ways.
Version 1
It’s pretty limited and does not allow you to access nested values. If you create a DL variable and tried to access pagePostAuthor (in the example below), you’d fail because it’s not in the root of the object (instead, it’s a direct child of attributes key).
<script> window.dataLayer = window.dataLayer || []; window.dataLayer.push({ "attributes": { 'pagePostAuthor': 'Julius Fedorovicius' } }); </script>
So if you wanted to fetch Post Author’s name, the object in the Data Layer should look like this:
<script> window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'pagePostAuthor': 'Julius Fedorovicius' }); </script>
See? There’s no attributes key and pagePostAuthor is at the root level.
That’s not the only limitation of Version 1. There’s also no merging available. Every time you push the data to the Data Layer, it will overwrite the entire key (that you’re pushing data to). Let me illustrate. Imagine that we have two Data Layer Pushes with different data. The first push contains a post object with only one parameter, pagePostAuthor, the other one includes the other two keys, pageCategory and pagePostType.
<script> //The 1st Push window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'post': { 'pagePostAuthor': 'Julius Fedorovicius' } }); //The 2nd Push window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'post': { 'pageCategory': 'google-tag-manager-tips', 'pagePostType': 'post' } }); </script>
As a final result, you’d have only two values in the Data Layer: pageCategory and pagePostType because the 2nd push has completely overwritten the data of the 1st push.
So what’s the point of the 1st Version? It sounds like a useless thing, you might say. Definitely not. For example, in Enhanced E-commerce, it’s really important not to have any artifacts (scraps) from previous pushes, meaning that every time a window.dataLayer.push occurs, it rewrites keys.
VERSION 2
The 2nd version is much more flexible. It allows you to access nested values, arrays, merge data.
Let’s go back to the previous example with two subsequent Data Layer Pushes. The first push contains only pagePostAuthor, the other one includes two more keys, pageCategory and pagePostType.
<script> //The 1st Push window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'pagePostAuthor': 'Julius Fedorovicius' }); //The 2nd Push window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'pageCategory': 'google-tag-manager-tips', 'pagePostType': 'post' }); </script>
Contrary to Version 1, in Version 2 all three values would remain in the Data Layer because they were not conflicting.
{ 'pagePostAuthor': 'Julius Fedorovicius', 'pageCategory': 'google-tag-manager-tips', 'pagePostType': 'post' }
If the 2nd Data Layer push also had the pagePostAuthor key, as a result, the final data in the Data Layer would have looked like this:
{ 'pagePostAuthor': 'John Doe', 'pageCategory': 'google-tag-manager-tips', 'pagePostType': 'post' }
This happened because pagePostAuthor from the 2nd push overwrote the pagePostAuthor from the 1st one. Simo Ahava has posted a detailed guide about Data Layer Versions. If you still have some questions, go check it out.
Default value
The last setting in the Data Layer Variable is Default Value. If you’re trying to access the value of a particular key in the Data Layer AND that key does not exist, “undefined” will be returned. Sometimes you might need to get a different default value, e.g. (not set), empty, or anything else. In that case, click the checkbox and set the default value.
Different data structures
Keep in mind that data can be stored in the data layer using different structures. Here’s an example (the key pagePostAuthor is in the root level)
<script> window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'pagePostAuthor': 'Julius Fedorovicius' }); </script>
Or this (pagePostAuthor key is now a descendant of the attributes key):
<script> window.dataLayer = window.dataLayer || []; window.dataLayer.push({ "attributes": { 'pagePostAuthor': 'Julius Fedorovicius' } }); </script>
Or even like this (there are two arrays that are the descendants of the transactionProducts key):
<script> window.dataLayer = window.dataLayer || []; dataLayer.push({ 'transactionProducts': [{ 'sku': 'DD44', 'name': 'T-Shirt', 'category': 'Apparel', 'price': 11.99, 'quantity': 1 },{ 'sku': 'AA1243544', 'name': 'Socks', 'category': 'Apparel', 'price': 9.99, 'quantity': 2 }] }); </script>
Every structure requires a bit different way how you should define the key in the Data Layer variable. In the case of the first example, the key should look like this:
In the 2nd example the correct variable name should be:
In the 3rd example, you should pull the first product’s category by entering the following name:
There’s a chance that the latter screenshot confused you a bit. Where did that 0 come from? If you want to better understand, how to pull the data from the Data Layer, read this blog post.
Further reading
This is neither the first nor the last post about Data Layer in this blog. So if you have any questions, check out these posts (or subscribe to my newsletter and stay up-to-date):
- What is Data Layer in Google Tag Manager?
- 3 ways to pull data from the Data Layer
- Custom Event trigger explained (because all Data Layer events can be turned into triggers with help of Custom Event Trigger)
Data Layer Variable: final words
Data Layer variable is one of the most (if not THE MOST) used the type of variables in my Google Tag Manager accounts.
With its help, you can access data stored in the Data Layer and utilize it in your tags, triggers, or even other variables. In this blog post, I’ve explained how to set up a variable, how to access data (which is stored using different data structures), what’s the difference between Version 1 and Version 2, etc.
If you have any questions, feel free to leave a comment below or drop me a tweet/LinkedIn message.
17 COMMENTS
Hi, great article, thanks for posting.
I have a data layer that looks as follows:
Do you know if the syntax of this data layer can be understood by GTM? What I'm trying to do is create a GTM custom variable that pulls in the value of the purchaseID key.
For the "Data Layer Variable Name" field in GTM I've tried three options: order:purchaseID, purchaseData:order:purchaseID and purchaseID . Neither of these three have worked.
Appreciate any advice.
Thanks
purchaseData = {
order:{
productsStr:";0158685229;1;43.05;;eVar25=100000240",
purchaseID:"WEB700000xxxxx",
promoCode:"",
zip:"60614",
state:"",
shippingMethod:"regular",
payMethod:"po"
}
};
Hey, first of all, dataLayer variable reads only that information which is in the "dataLayer" variable, not in some custom JS variable (like, in your case, purchaseData). A developer who created this data structure should push data to the Data Layer by using "dataLayer.push":
window.dataLayer = window.dataLayer || []
dataLayer.push({
order:{
productsStr:”;0158685229;1;43.05;;eVar25=100000240″,
purchaseID:”WEB700000xxxxx”,
promoCode:””,
zip:”60614″,
state:””,
shippingMethod:”regular”,
payMethod:”po”
}
});
So once this data is in the dataLayer, your Data Layer variable would be this: order.purchaseID
However, if that is not possible, you could try using JavaScript variable in GTM. Here's a guide that might help you.
Great thank you - I tried the JS variable approach and it worked
You're welcome!
I was using Data Layer Version 2
Thanks a lot for this post. I was struggling with having the same variable and how to deal with it and this post came through in the clutch.
Thank you, Julius! Your pages on DataLayers gave me much needed information about how to deal with "nested" variables that I could not find anywhere else. I wonder if I could ask one other question that I'm also having trouble finding the answer to:
Our developer has implemented DataLayers on our website using the window.dataLayer.push method. I have also set up the Variables in GTM for these variables. However, when debugging in GTM Preview, all variables appear as "undefined". I've seen some opaque references that indicate that a third step might be required- a "click trigger". Does something need to "fire" via a trigger in order for me to be able to see a variable value in GTM Debug mode or should I still be able to see the value populating without that? Thanks again!
No, nothing needs to be fired additionally if the data is already pushed to the Data Layer. My suggestions:
1. Open the Data Layer tab of the Preview and Debug console. Do you see that data pushed to the Data Layer.
2. If yes, maybe that data is stored in an array? In that case, you should define which exact array member do you wish to access. I've also explained this technique here https://www.analyticsmania.com/post/pull-data-from-data-layer-google-tag-manager-tutorial/
OK, thanks so much. I actually sent you a message via contact page but actually think I have figured it out. Thanks again!
Hey Julius (And others that may know),
Is there a cheat sheet for GTM Syntax's that can be used. Struggling to find anything that can help. Particular reference to the RegEx variable section.
Thanks,
Josh
Hey, Josh. Could you elaborate on what you're trying to achieve? There's no such thing as a GTM syntax. GTM utilizes already existing technologies like JavaScript, Regular Expressions, CSS Selectors, DOM, etc.
If you want to learn more about the Regular Expressions, just google it. Regex in GTM is no different that Regex somewhere else. You can start here https://www.apasters.com/blog/regex-guide-google-analytics-tag-manager/
Hi, can you please give a hint, what I am doing wrong, trying to reach price value in the following data layer code:
{
"event": "productClick",
"ecommerce": {
"currencyCode": "EUR",
"click": {
"actionField": {
"list": "General Product List",
"action": "click"
},
"products": [
{
"id": "HH381621013",
"name": "Arch of Triumph",
"price": 379.43,
"category": "Handle Bags",
"stocklevel": 0,
"brand": "",
"position": 1
}
]
}
},
I tried ecommerce.products.price and ecommerce.products.0.price.
Both don't work :(
Thank you for your help.
ecommerce.click.products.0.price
Hi Julius, can you please help me with this.
I would like to scrape the DOM to extract the model selected by the user and ideally I would like to track the model on successful form submission on this page https://au.skoda.com.au/request/test-drive.
1)How to Create datalayer variable in GTM which can be used to populate the values of model selected by user.Using javascript scrape the model information .
2)Set up a GTM tag that should trigger when a user is able to successfully submit a form.
Thank you for your help.
Wrong variable. Use this https://www.analyticsmania.com/post/dom-element-variable-in-google-tag-manager/
Hi, can you please give me direction here. I'm trying to reach price value (with decimal) in the following data layer code:
e-commerce: {
currencyCode: 'NZD',
checkout: {
actionField: {step: '2'},
products: [
{
category: "Auckland airport branch/extra',
metricl: 1,
id: '',
name: 'Unlimited'
price: '0.00'
variant: 'DISTANCE',
quantity: 1
},
{
id: 'A'
name: 'Toyota Yaris 2018 or similar (sub-compact car)',
brand: 'Toyota Yaris',
category: 'Auckland Airport branch/vehicle',
variant: 'vehicle',
metricl: 1,
price: '29.00',
quantity: 1
}
]
},
purchase: {
actionField: {
id: 'R0457C',
affiliation: 'djhfgdfnkdnfkjds for carcloud',
revenue: 29,
tax: 3.78,
coupon: ''
},
products: [
{
category: 'Auckland Airport branch/extra',
metricl: 1,
id: '',
name: 'Unlimited',
price: '0.00',
variant 'DISTANCE',
quantity: 1
},
{
id: 'A',
name: 'Toyota Yaris 2018 or Similar (Sub-Compact)',
brand: 'Toyota Yaris',
category: 'Auckland Airport brand/vehicle',
variant: 'vehicle',
metricl: 1,
price: '29.00',
quantity: 1
}
]
}
}
}
Great article, still. Thanks for writing! Is it possible to track a datalayer which has not been left empty in an event? For form tracking. No fields in my form are unique, thus I cannot track different enterFieldForms.