• Courses
    • Courses
    • Course bundles
  • Blog
  • Services
  • Resources
    • Youtube channel
    • E-books and Guides
    • GTM Recipes
    • View All Resources
    • GTM Community
    • GA4 community
  • About
    • About
    • Contact
  • Login
  • Courses
    • Courses
    • Course bundles
  • Blog
  • Services
  • Resources
    • Youtube channel
    • E-books and Guides
    • GTM Recipes
    • View All Resources
    • GTM Community
    • GA4 community
  • About
    • About
    • Contact
  • Login

January 1, 2022

Complete Google Tag Manager Data Layer Tutorial

Updated: January 1st, 2022

Data Layer is one of the main Google Tag Manager concepts which ensures maximum flexibility, portability, and ease of implementation. Without it, there would be no variables or triggers in GTM, therefore no tags would be fired. It is what keeps your tag management running properly. It is the key to unlocking Google Tag Manager’s potential.

In this blog, I’ve already published several articles related to this topic but they are pretty much scattered. That’s why I decided to collect all the important resources, tips, and knowledge (that I’ve accumulated so far) and put it in one place. This is an extended Google Tag Manager Data Layer tutorial that explains what the Data Layer is, why is it useful, how to use it, what are best practices, etc.

 

Table of Contents

This Google Tag Manager Data Layer tutorial is split into the following chapters:

+ Show table of contents +

  1. What is the Data Layer?
  2. Storing data in the Data Layer (dataLayer.push)
  3. Reading data from the Data Layer
    1. Data Layer Variable
    2. Data Layer Versions
    3. What about other data structures?
    4. Pull data from child keys
    5. Arrays
  4. Sending data from Data Layer to other tools
  5. Using Data Layer data as triggers
  6. Using Data Layer events as triggers
  7. Google Tag Manager Data Layer Tutorial: Final words

 

 

Video tutorial

If you prefer video content, here is a tutorial from my Youtube channel.

 

Two additional options where to learn Data Layer

Since the importance of this topic in Google Tag Manager is uncanny, I explain it in two of my premium GTM courses:

  1. Google Tag Manager Masterclass for Beginners
  2. Intermediate Google Tag Manager course

In the beginners’ course, we take a solid overview of what Data Layer is in general, why is it important, how to work with it.

In the Intermediate course, we take a lot deeper dive into topics that are not even explained in this blog post. Understanding the full potential (and technicalities) of the Data Layer is key to successful tracking implementations.

 

#1. What is Data Layer?

Technically speaking, a Data Layer is a JavaScript array that stores certain information. If that does not ring a bell, here’s a more simple explanation.

It’s an invisible/virtual layer of a website where you, your developers, or various tools can store data (about user, page content, etc.). From there, Google Tag Manager reads that information, uses it in tags/triggers/variables, or sends further to other tools, Google Analytics, Google Ads, Facebook Pixel, you name it.

Google Tag Manager Data Layer Tutorial Scheme

Once you place the Google Tag Manager container’s JavaScript Snippet in your website’s source code, the Data Layer is automatically created. You don’t need to add anything more (unless you want to fill it with additional data).

Google Tag Manager Data Layer can contain various information which can be done by placing an additional Data Layer snippet above Google Tag Manager snippet or by using dataLayer.push method.

Continue reading this Google Tag Manager Data Layer tutorial to find out why dataLayer.push should be your only option to add the data to the Data Layer.

 

#2. Storing data in the Data Layer (dataLayer.push)

There are two ways of how data can be pushed to the Data Layer. Actually, there is the only one you should use, but for the sake of knowledge I’ll mention both:

  1. By adding a Data Layer snippet above the GTM container snippet (this method is called Data Layer Declaration).
  2. Or by pushing data with dataLayer.push method. What’s the difference, you ask?

The first method is useful if you want to push any custom data right when the page loads. Example: product data when the product page loads. You might want to send that product data (from the Data Layer) to Facebook Pixel (with View Content event).

In this case, your developers should add a Data Layer snippet above the Google Tag Manager tracking container with parameters like product ID, product title, etc. Here’s an example:

<script>
 dataLayer = [{
 'productID': '123456',
 'productTitle': 'Very awesome product',
 'productPrice': '13.00'
 }];
</script>


<!-- Google Tag Manager --> 
... 
<!-- End Google Tag Manager -->

Later, with help of the Data Layer variable, you would be able to read that information and transfer to FB Pixel (continue reading this Google Tag Manager Data Layer tutorial and I’ll explain how to read that information).

The second method (recommended) (dataLayer.push) lets you push additional data when certain events occur on your website. Here are a few examples:

  1. You have a newsletter signup form (which cannot be easily tracked with a default GTM’s form listener). You should ask your website developer to fire a Data Layer event once a new subscriber has entered his/her email on your website:
    window.dataLayer.push({'event': 'new_subscriber'});
    

    If you wish you can ask your developer for additional information (e.g. form location (because you might have more than one form on the same page)).

    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
     'formLocation': 'footer',
     'event': 'new_subscriber'
     });
  2. When a visitor adds a product to his/her cart, a Data Layer event (containing the product’s information) could be fired.

IMPORTANT: After I wrote my first blog post about the Data Layer back in 2016 (later, I updated it several times), I was following Google’s documentation which suggested that I have to place dataLayer = [{}] above the Google Tag Manager snippet and dataLayer.push whenever an important event occurred.

But later I noticed multiple GTM experts suggesting that this is not the best practice. Instead, you should ALWAYS:

  1. Use dataLayer.push (forget dataLayer = [{}];)
  2. And upgrade it by adding window.

All examples in this blog post follow this rule, just like this one:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
 'event': new_subscriber
 });

If you want to learn more about dataLayer.push, read this guide.

Like this Google Tag Manager Data Layer tutorial so far? Consider subscribing! Just enter your email address in the form below and you’ll more of awesome GTM content.

 

 

#3. Reading Data from the Data Layer

Imagine, there are several authors in this blog:

  • Me
  • John Doe
  • Jack Torrance
  • etc.

I want to find out which authors write the most engaging content and then segment sessions in Google Analytics. I am using a DurecellTomi WordPress plugin that stores the post author name in the Data Layer. If you don’t have WP, ask a developer to add additional data points to the Data Layer.  The snippet looks like this:

<head>
   <script>
     window.dataLayer = window.dataLayer || [];
     window.dataLayer.push [{
       pagePostAuthor: 'Julius Fedorovicius'
     }];
   </script>
   <!-- Google Tag Manager -->
   ...
   <!-- End Google Tag Manager -->
</head>

It’s very important that the Data Layer snippet is placed above Google Tag Manager’s container code in your website’s code if you want to access that information with the Page View event.

 

#3.1. Data Layer Variable

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 a variable, you’ll need to specify the Data Layer key of which value you want to retrieve. When the Variable is resolved, it will return whatever was most recently pushed into the key. Easy as that!

Note: some screenshots in this article are still showing the older version of the GTM preview mode but that is just to show the general idea. It should not stop you from properly understanding this blog post.

Turn data layer variable into GTM variable

If I wanted to fetch pagePostAuthor value, I’d just need to set the pagePostAuthor key in variable’s settings.

Say, you want to send a Google Analytics event when someone leaves a comment. With every event, you also want to push the full name of the article’s author. 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 GTM account, you should go to Variables and create a new one with the following settings (dlv stands for data layer variable):

post author 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 Preview & Debug console.

Data Layer Variable in Preview and Debug console

 

#3.2. Data Layer Version

Another setting available in the Data Layer Variable is Version. When you select the Version, you’re instructing Google Tag Manager to treat the values in the data model in two different ways.

 

#3.2.1. 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 object. Let me illustrate. Imagine that we have two Data Layer Pushes with different data. 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>

As a final result, you’d have only two values in the Data Layer: pageCategory and pagePostType because it 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. That’s not entirely true. I’ve noticed that sometimes (e.g. in Enhanced E-commerce) it’s really important to have a “clean” Data Layer without previous values, meaning that every time a window.dataLayer.push occurs, it completely wipes out the old data and stores the new one.

 

#3.2.2. 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 pagePostAuthor key with value ‘John Doe’, 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.

 

#3.2.3. 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.

Data Layer Variable Default Value

 

#3.3. But what about other data structures?

Keep in mind that data can be stored in the Data Layer using different structures. Here’s an example where the key pagePostAuthor is in the root level:

<script>
 window.dataLayer = window.dataLayer || [];
 window.dataLayer.push({
    'pagePostAuthor': 'Julius Fedorovicius'
 });
</script>

Or this one (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>

In the last two examples, entering the key’s name (pagePostAuthor) is not enough, you couldn’t be able to get its value. There’s something else you need to know.

 

#3.4. Pull Data from Child Keys

Let’s try to put this as non-technical as possible: when keys are descendants of other keys, they are called child keys (to be honest, I’ve found various terms on this one, but child key sounds the most comprehensible for non-developers). In the example below, you can see that attributes are at the first level and pagePostAuthor is on the 2nd.

{
 attributes: {
   pagePostAuthor: 'Julius Fedorovicius'
 }
}

In order to pull its value, you should slightly change one setting in a variable (within Google Tag Manager). Instead of pagePostAuthor, you should enter attributes.pagePostAuthor as the Data Layer Variable Name.

attributes.pagePostAuthor

What if pagePostAuthor also had a child key? What would you do?

{
 attributes: {
    pagePostAuthor: {
       autorName: 'Julius Fedorovicius',
       authorTag: 'Google Tag Manager'
    }
 }
}

Inception we need to go deeper

That’s right. You should define the full path to that particular key: attributes.pagePostAuthor.authorName, and so on… and so on… Every level should be separated by a dot.

Accessing child keys in Data Layer is pretty common. When someone asks me to give an example, I always tell them about the AJAX listener which helps to track AJAX form submissions.

In my blog post, Google Tag Manager AJAX form tracking, I’ve explained how to use the AJAX listener which listens to all AJAX requests and pushes valuable information to the Data Layer. Here’s an example:

ajaxComplete - full response

There are a lot of nested keys. In order to pull data from Data Layer, you’ll need to use dot notation in the Data Layer variable’s settings, e.g. attributes.response.

dlv - attributes.response

 

#3.5. Pull Data from Array Members

I was working with a developer on the implementation of Google Analytics E-commerce tracking (standard, not enhanced). Following Google’s guidelines, I asked a developer to push successful order’s data to the Data Layer. Then, I could fetch that event via Transaction tag within Google Tag Manager.

It’s very important that the developer follows guidelines and pushes data using the structure as instructed by Google. Here’s the official example from their knowledge base:

<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
 'transactionId': '1234',
 'transactionAffiliation': 'Acme Clothing',
 'transactionTotal': 38.26,
 'transactionTax': 1.29,
 'transactionShipping': 5,
 '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>

“You know what?”, I asked myself, “This is very useful information”. I’d also want to push this order data to other marketing tools I’m using at Omnisend (e.g. Facebook Pixel). I was mostly interested in price, name, and quantity.

I tried my best and, unfortunately, failed. I used transactionProducts.price, transactionProducts.name, etc., but my newly created Data Layer variables always returned undefined. So what’s wrong?

Failed - undefined data layer variable

Notice anything suspicious? In my Standard Ecommerce example (taken from Google Knowledge Base), transactionProducts has 2 name keys, 2 price keys, etc. So how the heck can Google Tag Manager know which value I am interested in? The first or the second one? And what would happen if a user purchased 5 products?

What we are dealing here with is called arrays. transactionProducts has an array containing two products with the same collections of keys: sku, name, category, price, quantity.

In Javascript, if you want to pull the value of the first product’s price, you’d need to use transactionProducts[0].price (the index starts from 0), but Google Tag Manager does not support square brackets in this context, so you’d need to use dot notation, like this: transactionProducts.0.price.

access array members in data layer

In Google Tag Manager, your Data Layer variable should look like this:

transactionProducts.0.price

If there were 5 products in the array and you wanted to access the price of the 5th product, the Data Layer Variable name should be transactionProducts.4.price. Remember, the index here starts from zero, so the first product is actually not the 1st, but 0th.

Tired? If yes, then feel free to bookmark this Google Tag Manager Data Layer tutorial an come back later.

 

 

#4. Send Data from the Data Layer to Other Tools

A quick checkpoint in our Google Tag Manager Data Layer Tutorial. Let’s see what we have achieved so far:

  • Custom data was stored in the Data Layer (thanks to your coding skills, your developer’s coding skills, or some 3rd party plugin).
  • Google Tag Manager started recognizing that custom data (thanks to the Data Layer variable).
  • Now, we need to send this data to other tools, like Google Analytics.

By the way: if you are looking for a similar example but for Google Analytics 4, take a look at this guide. It explains how to send user properties (a.k.a. user-scoped custom dimensions) to GA4.

 

#4.1. Enable Preview and Debug Mode in Google Tag Manager

Let’s check if Google Tag Manager catches pricingPlan variable.

In your GTM panel, enter Preview and Debug mode (by clicking Preview button)

When Debug mode is enabled, a new tab should be loaded where you will have to enter the URL of your website

Click start and you will be redirected to that page.

Click Variables in the Preview mode’s tab and look for pricingPlan.  Check its value. If pricingPlan is undefined, you should double-check whether you have entered a correct Data Layer Variable name in GTM’s admin panel (by the way, it’s case-sensitive). In my case, pricingPlan variable is defined correctly, because I get the value Free.

 

#4.2. Create a Custom Dimension in Google Analytics

pagePostAuthor is a custom parameter that was defined by you (or your developer) so Google Analytics will not catch it by default. You need to create a custom dimension called pagePostAuthor (actually, you can call it whatever you want) in order to let Google Analytics know about this new parameter.

  • Login to your Google Analytics account.
  • Open your website’s account, click Admin. You should see something like this:
    Google Analytics Admin
  • Scroll down and in Property section click Custom definitions > Customer dimensions
    analytics custom dimensions
  • Click Create a custom dimension
  • Enter name pagePostAuthor (or anything else), choose User as a scope, and click Create. The user scope will apply this custom dimension to all further events of this particular user.
    Create dimension in Google Analytics
  • When a custom dimension is created, you’ll see a short code snippet.
    google analytics custom dimension code
    Take a closer look at the second line of code, there’s a dimension3. Number 3 is the index of pagePostAuthor custom dimension. Keep this in mind.

 

#4.3. Push pagePostAuthor Data Layer Variable to Google Analytics

  • Go back to your Google Tag Manager account.
  • Open Universal Analytics Pageview tag. If you don’t have one, create it.
  • Go to Tags and click New.
  • Enter the name for the tag – GA pageview (actually, you can name it whatever you want)
  • Click the Tag Configuration box.
    tag configuration bo
    Choose a tag type – Universal Analytics
    tag type universal analytics
  • Now it’s time to configure a tag. Enter Google Tracking ID (UA-xxxxxxx). In fact, it would be better if you used a variable with Google Analytics Settings, instead.
  • Track type – Pageview
  • Click More settings > Custom dimensions
  • Enter 3 in Index field (that’s the index that you got in step 3)
  • Enter {{dlv – pagePostAuthor}} Data Layer variable in the Dimension value field. In Google Tag Manager, variables are surrounded by double curly brackets {{}}.
    Custom dimensions in Google Tag Manager
  • In the Triggering section choose All pages.
  • This way with every page view you’ll also send the value of a pagePostAuthor variable as custom dimension No. 3.

That’s how you can transfer additional data from Google Tag Manager Data Layer to Google Analytics. But don’t limit yourself just to custom dimensions. You can use Data Layer variables in Google Analytics Event tags, Facebook Pixel, etc.

To see how you can use custom dimensions in action, read this guide on Moz blog.

 

#5. Using Data Layer Data as Triggers

Data Layer can also be used for more advanced tag-firing rules. For example, you can fire a Google Ads remarketing tag only when a user is on a Free plan. Let’s take a closer look at this example.

  • Open the Google Tag Manager admin panel.
  • Go to Tags and click New.
  • Enter a name, i.e. Google Ads remarketing tag
  • Choose Tag Type – Google Ads Remarketing
  • Enter Conversion ID and Conversion Label
  • Leave all other settings as default and click Continue
  • In the Triggering section, Click Plus icon create tag in triggers listin the top right corner and enter the name – I suggest “Pageview – Users with the free plan”. Choose Pageview as a trigger type.
  • You don’t want this tag to fire on every page. In This Trigger Fires on section, click Some Page Views and enter the following rule: dlv – pricingPlan equals Free. This means that Google Ads remarketing tag will fire only when pricingPlan Data Layer variable is exactly Free. Premium users will not trigger the rule.
    trigger configuration

 

#6. Using Data Layer Events as Triggers

Another common example of Data-layer-based triggers is to use events. In addition to custom data, you can also push events to the Data Layer by using window.dataLayer.push.

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
 'formLocation': 'footer',
 'event': 'new_subscriber'
 });

Parameter event indicates that this is a Data Layer event. All events can be seen in Preview and Debug mode’s stream.

new subscriber event

Now let’s set this event as a trigger for Google Analytics Event Tag.

  • Go to Triggers and click New
  • Enter name. I suggest calling it Custom – new email subscriber
  • Choose type – Custom event (all Data Layer events are treated as custom events in GTM).
  • Fire on – new_subscriber. You need to enter the exact title of the event that you see in Preview and Debug console.

Custom Trigger

Let’s get back to our window.dataLayer.push event example. Here’s the code:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
 'formLocation': ‘footer’,
 'event': new_subscriber
 });

Wouldn’t it be nice if we also passed the formLocation data to Google Analytics? Google Tag Manager will not catch this parameter by default, so we need to create another variable. Go to Variables > User-defined variables and click New.

  • I recommend naming it dlv – formPosition.
  • Choose type – Data Layer Variable. Variable Name – formPosition (that’s exactly how the parameter is called in the previous code example. Leave all other settings as is and click Create Variable.
    Form position - data layer variable

Finally, let’s create a Google Analytics Event tag when a new subscriber submits his/her email address.

  • Go to Tags and click New
  • Choose the product – Google Analytics
  • Choose Tag Type – Universal or Classic Analytics (depending on your currently installed version of GA).
  • Set Tracking ID parameter or choose Google Analytics Settings Variable.
  • Track type – Event
  • Category – Form Submission (this means that all events (related to this trigger) will have the same Category
  • Action – New subscriber
  • Label – {{dlv – formPosition}}. That’s the variable that we have just created. The value of this parameter will change depending on the position of your form. If you have 3 different forms on the same page, and they all fire the same new_subscriber Data Layer event but with different formPosition value, and Google Tag Manager will pass the correct value as GA event’s label. This is extremely useful if you want to understand which forms are performing better.
  • Click Continue
  • Fire On – Click More and choose a Data-layer-based trigger you’ve created before Custom – new email subscriber.
  • Done, you’re good to go!

GA Event Tag - New Email Subscriber

The following (and final) steps are:

  • Check all new tags in Google Tag Manager Preview and Debug console (whether they fire correctly)
  • Check Real-time reports in the Google Analytics account (whether new_subscriber events is working properly). If realtime reports are not working, read this troubleshooting guide.
  • Install Google Tag Assistant (in Chrome Browser) to make sure whether remarketing tag fires correctly (here’s a tutorial on how to use it)

Update: by the way, you can learn more about Custom Event Trigger in this blog post.

 

Google Tag Manager Data Layer: Conclusion

If you read the entire Google Tag Manager Data Layer tutorial, well done (and thank you)! If you skipped to the summary without reading the entire thing, I suggest bookmarking this page so you can come back later.

In this Google Tag Manager Data Layer tutorial, I’ve explained the key concepts of what the Data Layer is, why you should bother learning more about it, why is it important, etc. If you haven’t read this guide and just scrolled down to the conclusion, then spoiler alert, it’s SUPER IMPORTANT.

In a nutshell, here’s what the Data Layer is and how does it work:

  • Data Layer is a central place (virtual layer) of a website where you, your developers, various tools can store data (about user, his behavior, etc.). From there, Google Tag Manager reads that information and sends it further to other tools, Google Analytics, Google Ads, Facebook, etc.
  • Data Layer is not some magical place on a server where you keep the data. It’s a temporary data storage that is created after GTM has loaded and is completely wiped out whenever the page refreshes or is closed.
  • When the Google Tag Manager code is loaded on the page, the Data Layer is created automatically.
  • If you want to have some custom data in the Data Layer, you have to use window.dataLayer.push method to push the data. If you don’t know how to code, ask developers to do that or look for 3rd party plugins/tools which can do that.
  • By default, Google Tag Manager does not recognize custom data store in the DL, therefore you need to create Data Layer variables in GTM. In the case of Data Layer events, you also have to create Custom Event Triggers.
  • Finally, feel free to insert Data Layer variables in tags (within Google Tag Manager), e.g. Google Analytics event tag, Custom HTML tag, etc. Variables must be surrounded by double curly brackets {{ }}.

Is there anything I missed in this Google Tag Manager Data Layer tutorial? Let me know in the comments section below.

 

 

Julius Fedorovicius
In Google Tag Manager Tips
26 COMMENTS
Kevin Thomson
  • Dec 5 2017
  • Reply

Great detail Julius! My top tip to add - watch out for dataLayer values with commas, they break the tracking. For example a product category with commas included in an Ecommerce dataLayer will result in no transaction data being recorded in Google Analytics.

    Julius Fed
    • Dec 6 2017
    • Reply

    Thanks for the tip!

Saurabh Parikh
  • Jul 31 2018
  • Reply

Hi Julius,

Thanks for your reply.

Is there any other way we can add cart page multiple department value individual into Google Analytics?

Vaibhav
  • Nov 2 2018
  • Reply

I have a question regarding dataLayer variable. When submitting data to GTM and for analysis when we view the submitted data in GTM it gives us the access of submitted variable values. In addition to custom variable using standard variable we can get PageURL information also.
If I would like to restrict submission of complete URL with query string to GTM (e.g. if page access URL is https://yordomain.com/a.aspx?id=12345678 then I would like to submit only URL as https://yourdomain.com/a.aspx) then what changes are needed, Is it possible or not?

Please suggest.

    Julius Fedorovicius
    • Nov 2 2018
    • Reply

    If you want to work with particular parts of the URL, you should use a URL variable in GTM.

Vj
  • Dec 10 2018
  • Reply

Hello,

Thank you for writing this blog. I have an issue that I am facing with the data layer now. I am hoping someone can please help me with this: my problem is this: On my WordPress website when a user creates a comment, the button 'Submit' is clicked, when it is clicked, through code I push an event 'Comment added' to the datalayer. But when the button submit is clicked the page also reloads and in my header file.php that loads with every page the datalayer is recreated there before the GTM code. So basically my event 'Comment Added' does not fire to the Google Analytics platform. So how can I stop the datalayer from refreshing on a page reload? Or how can I ensure that there is only one datalayer for each session and not have it reload whenever the user navigates to another page?

    Julius Fedorovicius
    • Dec 10 2018
    • Reply

    The dataLayer does not refresh your page. The comment submission does (so one of the solutions, I guess, could be a timeout between the comment submission and the page refresh (that should be handled in your php code. I'm not a coder so I cannot help you here).

    The other solution could be to use transport: beacon setting in your GA tags. This is not supported on all browsers but in general, the support is pretty decent. Check this guide for more info https://www.simoahava.com/analytics/leverage-usebeacon-beforeunload-google-analytics/ (it mentions useBeacon but also directs to the most recent solution, transport: beacon).

    It will give a moment for the GA tag for properly fire before the browser tab/window is actually closed

Sonny
  • Dec 21 2018
  • Reply

thanks for the detailed go-through! i have one question, though.

the custom event value 'new_subscriber'

Fire on – new_subscriber. You need to enter the exact title of the event that you see in Preview and Debug console.

how can we set the exact title if the event value is set to a nested data layer e.g.

'event': [{
'name': 'pageView',
'category': 'Apparel',
'price': 11.99,
'quantity': 1
},{
'name': 'formView',
'category': 'Apparel',
'price': 9.99,
'quantity': 2
}]

the custom event in Tag Manager seem to place one the title of the event if there is only one event in the data layer. what if there are more than one event in the data layer? any idea?

    Julius Fedorovicius
    • Feb 1 2019
    • Reply

    "event" works in GTM only if it is a string. The trigger will not work if your "event" is an array.

Helder
  • Jan 31 2019
  • Reply

Hello

For marketeers this still is a very complex language. All of the articles that i read about Ecommerce GTM is written to developers or someone who understand the language, and so this one is. I really need somethng more basic. Its like, im a marketeer, i dont know anything about code or gtm. How can i set my GA ecommerce tracking on GTM, step by step?I dont want to be an expert now, i just want to get this set.

    Julius Fedorovicius
    • Jan 31 2019
    • Reply

    Hey, Ecommerce tracking is not a walk in a park. If you consider this explanation of the Data Layer complex (in this post), then I have some bad news: things will become even more complex if you plan to implement Ecommerce tracking only on your own.

    GTM is a simple tool to do basic stuff like track clicks, scrolling, video interactions (in most cases), etc. But there are things are more complex and might require even some coding basics.

    GTM is not some magic tool that totally replaces developers. In some cases you will need to work shoulder-to-shoulder with a developer. And dataLayer implementation (including ecommerce tracking) is one of those cases where developer's input is very much needed.

    Here's a guide on how to implement standard ecommerce in GA - https://www.analyticsmania.com/post/ecommerce-tracking-with-google-tag-manager/

    It is 100x easier than Enhanced Ecommerce tracking with GTN.

    And if you don't want to spend time learning or becoming expert and you just want to get things done, maybe you should hire a professional instead. In the meantime you could focus on other things that matter to your business.

Helder
  • Feb 1 2019
  • Reply

I do want to learn a little about it. I started already with some basic events and im preparing se set the ecommerce tracking, along with the developers team. But of course, they dont know what do i want to measure, i have to give them some instructions, like what data layer goes in what do i want to track, and so on. It must not be rocket science dough, i will get to manage it, but i would be glad to find some information that really help merketeer in this task, and doesnt make it more complex. Thanks for this article, bu i think standart tracking wont do it.

    Julius Fedorovicius
    • Feb 1 2019
    • Reply

    Gotcha. Keep in mind that Enhanced Ecommerce is one of the most difficult GA features to implement thus it won't be a walk in a park for marketers who are just starting. Eventually, you will have to dig deeper and understand what Data Layer is, how it works and how to instruct a developer where to implement it.

Adam O'Donnell
  • Jan 31 2020
  • Reply

Hey, is there is a limit to the number of values you can have in a dataLayer? Have a travel site with a TON of filters and data points that would be easiest to track in the dataLayer, but wasn't sure if there was a hard (or practical) limit that I should keep in mind.

Thanks again. Great post. I've been reading and re-reading it for a couple of years now.

    Julius Fedorovicius
    • Jan 31 2020
    • Reply

    I know that there is a limit of last 300 dalaLayer.pushes in the preview and debug mode (which has no serious implications). Regarding the number of data points in DL, I am not aware of limits (but that does not mean there is none). I just never faced it.

Majid
  • Feb 25 2020
  • Reply

Hello, You are the best at Google Tag Manager and GA. I have learned a lot at this website, i am a junior web developer and i am facing an issue, i want to implement Google Tag Manager and GA on a flight and hotel booking website the requirements are that i want to track what user has searched in the search box like in the case of flight booking i want to track the origin and destination, date and time and number of passengers who want travel that flight. after the search form is submitted which flight are shown to user after submitting the search form and which flight user select from the listing(search results). after that does the user go to add passengers details page and pay the amount and move to confirmation page.
first thing which i can't figure out is can i track what was the search query of user and which flights are shown to the user. also can i implement eCommerce or enhance eCommerce in this scenario or there can be some other good option.
Your response will be very helpful for me
Thanks

    Adam O'Donnell
    • Feb 25 2020
    • Reply

    Definitely not a one- or two-step solution. For tracking the search boxes you'll probably want to store those values in the data layer. You can then pass them to GA using variables in Google Tag Manager. As far as which flights the user selects you could set events that capture the values when the user clicks "select" or whatever. But I'd probably utilize the data layer here as well. You also mention the next steps, which is basically the sales funnel. You can set goals for tracking whether uses do the 1 > 2 > 3, etc. step process to complete the purchase. This would be easy if your funnel isn't too complicated. Otherwise you can use events in addition to tracking the URL.

      Majid
      • Feb 26 2020
      • Reply

      Thank you very much Adam O'Donnell, As a junior web developer i under stand the concept of data layer and i know how to set values in data layer and how to get value of a single data layer variable in Google Tag Manager. but the problem is how i will see all the values of data layer in Google analytics. The data layer below is a dome data layer of flight search form.
      dataLayer.push({
      'form_type':'flight_search_form',
      'origin' : 'London, United Kingdom, (LON) - All Airports',
      'destination' : 'Dubai, United Arab Emirates , (DXB) - Dubai International Airport',
      'departing' : '03/17/2020',
      'return' : '03/19/2020',
      'trip_type' : 'Round Trip',
      'travellers' : '2',
      'class' : 'business',
      'currency' : 'USD',

      })
      now i know how to get the values of all the variables in data layer one by one. but i don't know if i can add a complete data layer in one variable in Google Tag Manager? I can attach variable to the "search form submit" event but is there any complete chart or table which can show me what query user searched which flights are shown to the user which flight user and does he went to the confirm booking or not. My main problem is how will i see all the data pushed in the data layer on search form submit event in google analytics.
      Hope you can understand the question.

Majid
  • Feb 26 2020
  • Reply

Thank you very much Adam O'Donnell, As a junior web developer i under stand the concept of data layer and i know how to set values in data layer and how to get value of a single data layer variable in Google Tag Manager. but the problem is how i will see all the values of data layer in Google analytics. The data layer below is a dome data layer of flight search form.
dataLayer.push({
'form_type':'flight_search_form',
'origin' : 'London, United Kingdom, (LON) - All Airports',
'destination' : 'Dubai, United Arab Emirates , (DXB) - Dubai International Airport',
'departing' : '03/17/2020',
'return' : '03/19/2020',
'trip_type' : 'Round Trip',
'travellers' : '2',
'class' : 'business',
'currency' : 'USD',

})
now i know how to get the values of all the variables in data layer one by one. but i don't know if i can add a complete data layer in one variable in Google Tag Manager? I can attach variable to the "search form submit" event but is there any complete chart or table which can show me what query user searched which flights are shown to the user which flight user and does he went to the confirm booking or not. My main problem is how will i see all the data pushed in the data layer on search form submit event in google analytics.
Hope you can understand the question.

Adam O'Donnell
  • Feb 26 2020
  • Reply

Well, Julius or someone else might have better ideas, but my work is very similar to this and I just create variables for them and pull them out one-by-one as you say. You can have more than one event fire at the same time (or sequence them so that they go in the order you want). Maybe one captures the flight info like to, from and dates, then another that captures class so you can track how many biz class vs. coach or something. You can also stack them together - i.e. in Category put "Flight Searches", then Action gets your location variables such as "{{Flight-Origin}} to {{Flight-Destination}}", then do the same with dates in your Label.

But before you start getting into all that, I would suggest stopping and thinking about what you need to track and why. Not saying you don't want to track anything and everything, but do you need to track whether they chose USD during the search process? I don't know your needs so maybe, but it seems like something I'd be worried about at the end when they actually purchase. If I'm understanding you correctly, you're tracking the search form and then you'll use ecommerce to capture the actual details of the purchase. So, what I do is track what they searched for vs. what they actually purchased. That's why I put the destination in an eventAction, along with a specific category. And for most of my events I use a timestamp in the eventLabel so I can string the session steps together if I need to. Then I'll have another event that captures dates because it's of interest to me to track how far out people are searching for travel options. But that's a different report so it's a different event.

Again, just my take. Others might have other ideas. I would just say that your ecomm is going to capture all the purchase details. For search data you need to think about what is actually needed and how you want to use it.

Majid
  • Feb 26 2020
  • Reply

Thank you. I am trying to add custom dimensions and adding the all the data layer variables to that custom dimension i hope that this can give me some lead. if you can give any better advice than custom dimensions then i can implement that also.

    Adam O'Donnell
    • Feb 26 2020
    • Reply

    You can pass them over as custom dimensions too. Usually through your main page view tag, but there are other ways. I would just caution that you only have like 20 custom dimensions and you probably want to use a couple of those for high priority things like client IDs. You can get creative with multiple Views but that can get sticky so just be careful how many data layer values are necessary as custom dimensions.

Laurynas
  • Jun 23 2020
  • Reply

Thanks for the article.

My question is regarding the dynamics of data. I've never implemented data layer. All of the examples seem to have the key values set by developer (since it's in ''), unless I am looking at it wrong. Looking at the code I would image, the key value should be a variable that returns value. Am I incorrect at this point?

dataLayer.push({
'commentAuthor':'Laurynas'
})

how does it know that this comment's author is 'Laurynas'?

I would guess that it should be:

//some variable to grab the data
var commentAuthor = ;

dataLayer.push({
'commentAuthor': commentAuthor
})

    Julius Fedorovicius
    • Jun 25 2020
    • Reply

    Yes, you are right. In the code, there will be some variable that outputs the desired value, e.g. comment author's name. But on different websites, the names of those variables will be different, therefore, I cannot give you a very specific universal code example.

Shaheer
  • Nov 22 2021
  • Reply

Hi Julius,

Hands down, It's an awesome blog. I have learnt a lot from it. I do have a question too.

Talking about pushing custom events via datalayer, my concern is, how does GTM know that it has to show "FormSubmitted" event when the only thing we did was just initiate a key-value parameter as defined above for subscribe form

"""

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'formLocation': 'footer',
'event': 'new_subscriber'
});

"""

I hope my question us easy to be answered :)

    Julius Fedorovicius
    • Nov 24 2021
    • Reply

    From your code, it won't show "FormSubmitted". It will show "new_subscriber" because that is the value in the "event" key.

Leave a comment Cancel reply

Your email address will not be published. Required fields are marked *

 

Hi, I'm Julius Fedorovicius and I'm here to help you learn Google Tag Manager and Google Analytics. Join thousands of other digital marketers and digital analysts in this exciting journey. Read more
Analytics Mania
  • Google Tag Manager Courses
  • Google Tag Manager Recipes
  • Google Tag Manager Resources
  • Google Tag Manager Community
  • Login to courses
Follow Analytics Mania
  • Subscribe to newsletter
  • RSS feed
Recent Posts
  • Two Link Click Events in Google Tag Manager Preview Mode
  • Where to Find Video Engagement Data in Google Analytics 4?
  • Where to Find File Download Data in Google Analytics 4?
Analytics Mania - Google Tag Manager and Google Analytics Blog | Privacy Policy
Manage Cookie Settings