
May 6, 2020
3 Ways to Pull Data from Data Layer with Google Tag Manager
Updated: May 6th, 2020. Data Layer is the foundation, which Google Tag Manager heavily relies on. It ensures maximum flexibility, portability, and ease of implementation. In my other blog post, I have explained how it works and how you can the most out of it. However, not all aspects were covered there. Since data can be saved using different structures, it should be accessed differently, as well. In today’s blog post, I’ll explain 3 ways how you should pull data from the data layer.
Although all three methods include Data Layer Variable that can be created in Google Tag Manager container, their settings will differ a bit.
If you have read my guide about GTM Preview and Debug mode, you already know that the Data Layer tab is the most undervalued and totally untapped part of the GTM debug console, which is forgotten by beginners and (especially) intermediate users.
This tab shows the exact message object as it was pushed to the data layer for the selected event, and what the data layer looks like after the message transaction is complete.
In other words, you can see all data that is currently available in the data layer and what values were available after every Google Tag Manager event. And the best part: every data point (pushed to data layer) can be turned into a variable in Google Tag Manager.
Table of Contents
- Before we continue
- Access primitive values (e.g., strings, numbers) in the Data Layer
- Access nested values in the Data Layer
- Access arrays in the Data Layer
- Final words
#0. Before we continue: this topic is also thoroughly explained in the Intermediate GTM Course
In this blog post, you’ll take a glimpse at 3 data types in JavaScript: strings, objects, and arrays. However, if you want to dive a bit deeper and properly understand how they work in GTM, enroll in my Intermediate Google Tag Manager course.

#1. Accessing first-level keys (a.k.a. primitive values)
You’re probably asking why did I call them “first-level keys”? I’ll explain that at the end of this chapter.
For my WordPress blog I’m using DuracellTomi’s GTM plugin, which is pushing some keys and values with each page load:
- Key: pagePostType, value: post
- Key: pagePostType2, value: single-post
- Key: pageCategory, value: google-tag-manager-tips
- Key: pagePostAuthor, value: Julius Fedorovicius
See the screenshot below.
With help of Google Tag Manager, I can easily turn each one of them into data layer variables and re-use them in other tags.
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 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 Variables tab of P&D console.
Oh, I almost forgot. You’re probably still thinking, why did I call it “First-level key”. Well, that’s because all those 4 keys have no parent keys. Let me illustrate. Here’s the example where the key is on the first level.
{ pagePostAuthor: 'Julius Fedorovicius' }
And here’s 2nd level key, because pagePostAuthor is a descendant of attributes key:
{ attributes: { pagePostAuthor: 'Julius Fedorovicius' } }
In the next chapter, I’ll explain how you can pull data from the data layer if the key is not on the first level.
#2. Pull the data from child keys (a.k.a. nested fields)
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 Data Layer Variable Name.
What if pagePostAuthor also had a child key? What would you do?
{ attributes: { pagePostAuthor: 'Julius Fedorovicius': { someOtherKey: 'example' } } }
That’s right. You should define the full path to that particular key: attributes.pagePostAuthor.someOtherKey, and so on… and so on… Every level should be separated by a dot.
Accessing child keys in the data layer is pretty common. When someone asks me to give an example, I always tell them about 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 AJAX listener (by Bounteous). It listens to all AJAX requests and pushes their data to the data layer. Here’s an example:
There are a lot of nested keys. In order to pull data from the data layer, you’ll need to use dot notation in the data layer variable’s settings, e.g. attributes.response.
#3. Pull the data from array members
I was working with a developer on the implementation of Google Analytics Ecommerce 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 (and its data) 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 (e.g. Facebook Pixel). I was mostly interested in price, name, and quantity.
So I tried Method #2 (from this blog post) and failed. I used transactionProducts.price, transactionProducts.name, etc., but my newly created data layer variables always returned undefined. So what’s wrong?
Notice anything suspicious? In my Standard Ecommerce example (taken from Google’s 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. The 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.
In Google Tag Manager, your data layer variable should look like this:
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.
Final words on pulling data from the Data Layer
Since data can be saved using different structures, it should be accessed differently, as well.
Now, you know how to pull data from the data layer in 3 different ways. Although they all use the same Data Layer Variable, their names are different which depend on the data structure – arrays, nested keys, or single (first-level) keys.
28 COMMENTS
Julius, thank you for these posts. I am able using example 2 ( google tag manager ajax form tracking ) and the ajax listener to pull the data I need but I do not know how to display the data in my Analytics report. The data I am pulling is a Zip Code entered into a input field, I am stuck at the last step that should be trigger but none of the options seem correct
Hey,
1. Zip code is a Personally Identifiable Information (PII) which cannot be stored in Google Analytics. In 2011 a California State Supreme court ruled that Zip code is a PII. If Google notices that you're sending it, your account will be banned. Learn more how to avoid storing PII https://support.google.com/analytics/answer/6366371?hl=en.
2. After you pull the data from the data layer (by creating Data Layer variables), just enter them in Universal Analytics Event tag's fields (e.g. Event Action or Event Label). In those fields, variable must be surrounded by curly brackets {{variableName}}.
3. If you wish to pull the value from web form's input field, Lunametrics have published a tutorial https://www.lunametrics.com/blog/2016/09/22/tracking-form-field-values-google-tag-manager/
Hello.
Thank you por your post. Nice information.
I have a doubt: can I create a dataLayer inside the Google Tag Manager? for example place the code of the dataLayer inside a custom HTML tag.
Is any way to do that?
In other words create the datalayer without touching the code.
Thank you
When GTM loads, it automatically creates a data layer. If you want to push some data into it, ]you can use window.dataLayer.push method to do that (with Custom HTML tag). I've described how Data Layer works in detail here https://www.analyticsmania.com/post/ultimate-google-tag-manager-data-layer-tutorial/.
You'll also find how to push data to the data layer.
Hi, i have one question: i push event from GTM custom html tag. Is there a way to make the GTM dataLayer variable that is picking value from this event get the updated value? Right now the custom event is fired from this tag on form submit, there is no page reload and it's after window loaded, so the datalayer variable will be undefined. Is there any way to solve this using dataLayer variable? Or the easiest is just to use JS variable?
Data Layer Variable will start returning some value only when that information is pushed to the Data Layer.
>Right now the custom event is fired from this tag on form submit, there is no page reload and it's after window loaded, so the datalayer variable will be undefined.
If you push an "event" key and some custom parameters to the Data Layer, those custom parameters can be retrieved with the Data Layer variables. Just include the "event" key in the dataLayer.push
Hi Julius,
Thanks for writing this blog. It's super useful for non-technical people like myself. I have a question.
How do I pull out "option in actionField" variable from
dataLayer.push({
'event': 'checkout',
'ecommerce': {
'checkout': {
'actionField': {'step': 1, 'option': 'Visa'},
'products': [{
'name': 'Triblend Android T-Shirt',
'id': '12345',
'price': '15.25',
'brand': 'Google',
'category': 'Apparel',
'variant': 'Gray',
'quantity': 1
Is that "ecommerce.checkout.actionField.option" or "ecommerce.checkout.actionField.0.option"?
Hey, it's ecommerce.checkout.actionField.option because actionField is an object, not an array. Arrays are surrounded by brackets [], objects are surrounded by curly brackets {}.
The best way to find out for you in the future is to check it in the Preview and Debug mode. Create a Data Layer Variable, refresh preview mode and go to the website where that dataLayer.push occurs. If variable's value is undefined, something's wrong. If you see the correct value, then you did everything correctly.
Hey Julius, nice article! Really difficult to find useful articles.
But there is one question:
The used "dataLayer.push({ 'transactionId'..." isn´t the right one for enhanced ecommerce tracking, or? ususal my DataLayer looks different and ist not only based on the basic transaction. In one project i have seen a tansaction tag, which is running because of the datalayer u are using too. But at the Checkout Behaviour Analysis i see the steps which i have defined via gtm, but at the last point no transaction. I hope u know what i mean ;)
Hey, that snippet is supported only in the Standard Ecommerce. Enhance Ecommerce require totally different implementation and codes pushed to the data layer. You need to push "purchase" event. Here's a guide I always recommend to read https://canonicalized.com/enhanced-ecommerce-tag-manager/.
Good article, and really a bridge to go from simple data layer usage ecomm for me ... However, what would be the best and easiest way to fill the datalayer with all this data ? I don't think that duraceltomi's plugin goes this far ...
Hey, you'll need to cooperate with a developer to have that custom data in the Data Layer.
Thanks ... actually, I found out that gtm4wp does populate the data layer with the complete e-commerce data ... it's a beta feature, but it works great ...
Good article, and really a bridge to go from simple data layer usage ecomm for me ... However, what would be the best and easiest way to fill the datalayer with all this data ? I don't think that duraceltomi's plugin goes this far ... ...
Hey, the easiest way is to either use a plugin (so for WP it is still the duracelltomi's plugin) or to ask a developer to push some needed data to the Data Layer.
Exactly what I needed, thanks!
Brilliant. I was really struggling with a new tag but your explanation about child keys solved the problem.
Thank you!
Thanks Julius, Learned a lot from your blog. Keep up the good work.
Julius this is brilliant! Suppose I don't want to push the data into GA, but into a Google Sheet spreadsheet. What setup would I use to push that from GTM to that spreadsheet? Any thoughts or articles?
It would much more reliable if you just asked developers to push the data from your server to zapier that is connected to google sheets (and avoid GTN here). Or maybe utilize google appscript. Unfortunately, I'm not that experienced here so I cannot give you a more precise advice.
Thank you very much Julius for your useful blogposts. I follow and advice your content.
Hi,
I ticked the "Use Data Layer" as you and many other sites recommend and It doesn't work as I expected. I expected that all these data like a product is, name, category etc. will be added to GA reports automatically. But I cannot find these data. What should I do?
Thanks for your help.
If someone clicks a product, and you have the product click information PROPERLY formatted in the Data Layer, then all data points of that single dataLayer.push will eventually appear in GA (not in real-time, but at within 24 hours. Usually, less).
If you don't see any information in GA after 24 hours, most likely your dataLayer.push is not following the strict requirements of Google Analytics EE.
Amazing work! Big fan of your explanations. Helped me integrate GTM throughout!
Thanks Julius,
What if I want to get all items from an array? (and I don't know how many items there are?)
Also, how can I calculate the basket value can I run a custom JS function and do the math?
I've set up a variable called 'funding_value' and a tag that pulls this value from a form:
<script>
jQuery('[name="next-step-2"]').click(function(){
var funding_val = jQuery('#required-funding-amount').val();
if(parseInt(funding_val) != NaN)
{
dataLayer.push({'event':'funding_event','funding_value':parseInt(funding_val)});
}
});
</script>
How do I insert this 'funding_value' into a facebook conversion:
<script>
fbq('track', 'Lead', {
value: funding_value
});
</script>
I'm new to javascript, just need to know how to make this tag actually insert the value of funding_value into the fbq script.
Hey Julius, thank you so much for this post after hours searching why my dataLayer variable wasn't being found, I saw your post and discovered that to pull data from an array I had to add a ".0." so thank you so much.
You just earned a new follower!