Upcoming LunaMetrics Seminars
Boston, Apr 6-10 Los Angeles, Apr 13-16 Atlanta, Apr 27-30 Washington DC, May 11-15

Unlock the Data Layer: A Non-Developer’s Guide to Google Tag Manager

key in lock

There’s nothing mysterious about the data layer for Google Tag Manager. It’s just a place to hold information so your tags can refer to that info when they need it. Do you need a developer or not though? Can you use the data layer if you’re not a developer?

This post discusses how information gets into the data layer, and how tags use that information. Understanding the data layer is the key to making the most of your Tag Manager implementation. Along the way we’ll see where you need a developer and where you can do things yourself.

How does information get into the data layer?

Information is either written into the data layer as part of the page code, or it’s pushed to the data layer later as certain events occur. The information may vary by page or may change depending on a visitor’s actions.

The information may need to be pulled from the back-end. It may need to be formatted in a specific way as in the case of ecommerce data for Google Analytics.

You can push a lot of information through Tag Manager to the data layer, but some will inevitably have to go through your site’s developers.

1. The page can specify its own data layer

When the page loads, its code can contain the data layer with information specific to the content of that page. Your developers create the data layer by writing it into the page code. Make sure the data layer comes before the code with the Tag Manager container snippet.

For example, each article page of a news site might load with a data layer containing the page category (Sports, Politics, Entertainment), author information, and a taxonomy of topical keywords relevant to the article. The code on the page might look like this:

GTM data layer for page content

On an ecommerce site, each product page might load with a data layer containing the product category, brand information, product ID number, and any number of sub-categories (style, size, color).

The order confirmation page needs to load with all the information needed to do ecommerce tracking for each purchase. This means the pre-rendered code of that page would read the details of the order from the customer database and write them into a specific format, such as this format for Google Analytics:

data layer info for ecommerce

The pre-rendered code for the order confirmation page would compose the data layer by filling in each piece of information for the overall transaction (order ID, total amount, etc.), and then looping through each item that was purchased to add its information in turn.

2. Tag Manager creates the data layer by default

If you don’t have ecommerce and you don’t want to specify page categories or other page information, then you don’t have to include the data layer in your page code.

If the page code doesn’t explicitly create the data layer, Tag Manager will create it. After the page loads, you can see the data layer contained 3 events, in succession: gtm.js, gtm.dom, and gtm.load. These events will always appear in the data layer, unless something goes terribly wrong. If you examine the data layer in the console, you’ll see something like this:

data layer created by default

When GTM starts, the data layer gets the gtm.js event. This is followed by DOM-ready (gtm.dom event) which means the document object model has been constructed from the various elements of the page. A bit later the window and its content are fully loaded, and the gtm.load event is pushed to the data layer.

Of course if you had a data layer already specified in your page code, you’d see another object before all of the default objects, something like this:

default data layer plus page info

3. You push info to the data layer after the page loads

Once the data layer is created, either by your page code or by Tag Manager (by default), you can continue to add information to it as visitors interact with the page. If a visitor downloads a file, clicks a link, or submits a form, you can tell Tag Manager to send automatic events to the data layer.

If a visitor hovers over a menu or estimates their shipping costs, you can write custom HTML tags to send events to the data layer. And you can add information about those events to the data layer, too, such as how long they hovered or what they entered in the shipping form field.

data layer with added event info

Above you see event information that was added to the data layer after the visitor hovered over some text on the home page (“/”) indicating 1 item in the cart. The event value is the number of seconds the visitor hovered.

Events like these are not available as automatic events (yet) in Tag Manager. I used jQuery to capture them. So even though I didn’t have to go through the site’s developers, I did need to write some code myself to get what I wanted. I’ll share it in a future post if there’s interest.

How do tags use information in the data layer?

Tags can use the data layer in at least two different ways.

1. To access certain types of information

A tag may need information that can’t be hard-coded into the tag. Some tags only require your account number, which never changes. But others may ask for a product ID or the transaction total or any type of info that changes depending on the page content or a visitor’s action.

Many times you can use jQuery or otherwise parse the page content to get the information you need. Using custom javascript macros can be the right solution(and a good topic for another blog post).

Other times you’ll find it more efficient for your developers to write the information you need into the data layer. For example, some conversion tags ask for the product total, or subtotal before shipping and tax, rather than the overall transaction total. You could write some code inside Tag Manager to calculate this amount, but it would be much better for your developers to drop the subtotal into the data layer from the back-end.

Additional transaction data in the data layer

Similarly, if a product ID appears in text on the page, you could have Tag Manager use some jQuery to find it and push it to the data layer. But a better solution would be to have your developers simply add that information to the data layer for each product page.

Event tracking tags need to pull from the data layer any information that distinguishes the specific event you want to track. For example, my ‘cart-hover’ event pushes information to the data layer related to the number of items in the cart and how long the visitor hovered. Then when the tag fires, it can pull that info back out of the data layer and send it to Google Analytics.

I’ve also dropped Sayf Sharif’s YouTube tracking script into a custom HTML tag and then pulled info back out of the data layer for my Google Analytics video events. I simply changed the lines with _gaq.push to the syntax for dataLayer.push and then wrote my event tag to read what I pushed.

YouTube info sent to data layer

For product reviews, I’ve taken the product ID out of the data layer to use as an event label. You could do something similar with a product video embedded on a product page.

See more examples in Jonathan Weber’s post on automated event tracking in Google Tag Manager.

2. To go beyond the basic tag firing rules

The most basic rules fire tags based on the URL of the page. But a tag also may be fired or not fired depending on information that appears in the data layer. You can write a rule with one or more conditions based on any type of information, no matter whether it’s related to an event or to the page itself.

For example, you might have a condition that fires a tag only if the data layer has a variable named ‘event’ with the value ‘cart-hover’. Or you might have a condition that fires a tag only if the data layer has a variable named ‘pageCategory’ with the value ‘Sports’.

You can add multiple conditions to a rule, and they all must be true in order for the rule to fire a tag. For example, you could require the value of an event to be greater than a certain amount in order for a tag to fire, such as hovering for 2 or more seconds for the ‘cart-hover’ event.

rules from data layer values

Keep in mind that you can’t have a condition where {{event}} equals ABC AND {{event}} equals XYZ. Each event can trigger its own rule, but Google Tag Manager will only evaluate one event at a time.

data layer warning about events

What challenges have you faced in implementing the data layer with Google Tag Manager? Have you devised any creative solutions or discovered new opportunities for working with the data layer? Please share in the comments.

Dorcas Alexander

About Dorcas Alexander

Dorcas Alexander is a Digital Analyst working with Google Analytics. Her path to LunaMetrics included stints in ad agency creative, math, computer science, language technology research, and corporate training. She loves to learn and teach what she’s learned. One of the top-rated tournament Scrabble players in Pennsylvania, Dorcas has an insatiable drive to compete and win. “Impossible” is not in her vocabulary.


50 Responses to “Unlock the Data Layer: A Non-Developer’s Guide to Google Tag Manager”

Superclive says:

Stunning post — best I’ve read all week (and I’ve read a lot!)

I’ve experimented quite a lot with auto-events in GTM but for complex Event Tracking where events still need to be pushed from the page, is the data layer always explicitly required or can we use existing onMousedown / onClick?

Re: your comment:

> I did need to write some code myself to get
> what I wanted. I’ll share it in a future post
> if there’s interest.

There’s interest!

Dorcas Alexander Dorcas Alexander says:

Hi Superclive, You could put GA code into existing onclick or onmousedown events on the page, but that dilutes the benefits of using Tag Manager. It’s better to have all your GA code in Tag Manager so you don’t have to remember which events are inline and which are in GTM. You’ll have fewer maintenance issues.

Ian Lyons says:

Great post. The only thing I would add is how to see the data layer because as a non-techie, this took me a while to figure out …

In Chrome, right click in the page and select “Inspect Element”, click on the Console tab at the top, then type dataLayer at the > prompt – note the capital L

In Safari, you first need to enable “Show Develop menu” in the Advanced Preferences, then you can right-click and “Inspect Element”. Click on the Console button and then type dataLayer at the > prompt

Dorcas Alexander Dorcas Alexander says:

Great tips! Thanks, Ian. In Firefox, go to the main menu and choose Web Developer > Web Console, type dataLayer at the prompt and then click on [object Array] to display the contents in the right panel. And in Internet Explorer, click the gear and choose F12 developer tools, then choose the Script tab and click Watch and “add to watch list” where you type in dataLayer. In some browsers (like Chrome) you can just press F12 to go straight to the developer tools.

my business partner and I are trying to implement data layers to our site which is an e-commerce site, prestashop as the CMS. We are familiar with GTM just not sure how what we need. Do add the data layer script to all products or just one? If it’s all products do we use the same one? Do you use dummy content? ‘transactionId': ‘1234’, 1234 would be the dummy content.

Thank you in advance for your time.

dataLayer = [{
‘transactionId': ‘1234’,
‘transactionAffiliation': ‘Acme Clothing’,
‘transactionTotal': 11.99,
‘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

Dorcas Alexander Dorcas Alexander says:

Hi John, In order to do ecommerce tracking, you only need a data layer (like the one you’ve copied here) on the receipt page where the customer’s final transaction is confirmed. This receipt page would also be the page where you fire the GTM ecommerce tag which tracks the transaction and items in the transaction. You can add the data layer to all your product pages, but GTM will ignore it unless you are also firing a tag on those product pages that needs info from the data layer. For example, you might want to fire an event if someone watches a video on a product page, and your GTM event tag could read info about that product from the data layer (such as product name and/or category that you’ve stored in the data layer on that page) and send it as the event label.

Evan Parker says:

Thanks for getting the word out about the GTM data layer. GTM is, IMHO, *the* biggest thing to happen to advanced analytics implementations in years, and the data layer is no small part of its power!

brommersman says:

Excellent post. This has inspired me to fix a problem I’d be having with ecommerce tracking where the data layer was constructed in a custom tag in the google tag manager.

The main thing I think is easy to miss is how to act on custom events.
For example


Means that the {{event}} with value ‘transaction’ is essentially fired and so can be listened for in other triggering rules. I used this in a firing rule where the Google Analytics(TrackType=Transaction) is used so I set up my dataLayer correctly before firing the tag.

This (after a few weeks of head scratching) is a relatively simple thing solution that I missed.

I can send further details of my solution if anyone thinks it would be useful?

Dorcas Alexander Dorcas Alexander says:

Hi brommersman, Your example does indeed highlight the power of Google Tag Manager. If you use Custom HTML Tag X construct your own data layer variables to hold the necessary values for ecommerce tracking, then at the end of Tag X’s code you can push an event to the data layer that essentially says, “Ready!” and wait to fire the ecommerce tag when you detect that event. Great idea!

Denis says:

Great post! The question I have is about about e-commerce tracking in GTM. I understand how the sample example works (transactionId, transactionProducts). But the client that we have has the business of vacation reservations. We need to implement e-commerce tracking via GTM but using the variable like ‘reservation/bookingId, reservationType, reservationProduct (like Start Date, End Date) and so on. So what should I do to get it tracked correctly in GTM and UA? As far as I understand you cannot just simply change transactionId to something else in the tracking code? And if so, what should I do? Thank you very much!

Dorcas Alexander Dorcas Alexander says:

Hi Denis, Right, you can’t just change the dataLayer variable names, because the built-in UA transaction tag expects to see transactionId, etc. So you have to feed the info from your variables into the corresponding dataLayer variables as much as you can. So you might populate transactionId with the value of bookingId, and productCategory with reservationType, etc. Where you have two values like Start Date and End Date, you might have to concatenate those into one value and use that value to populate productName. Or maybe you’d like to simply calculate the number of days and send that as the value of productName. It’s the number of variables more than their names that restrict you, and the fact that a few of the variables are strictly reserved. You can’t change price or quantity because UA expects to treat them as such. So for a booking you’d almost always have quantity=1 and price=price of the booking. Hope that helps.

Denis says:

Thank you for the response. It’s very helpful. But what about introducing custom variables (dimensions and metrics) in order to track all values that fit the biz environment (bookingId, etc)?Or there is no way way to insert them into e-commerce tracking through GTM?

Dorcas Alexander Dorcas Alexander says:

Hi Denis, That’s an interesting idea and I have to admit I haven’t had a client for which I’ve tried that yet. I suppose you would need to decide whether you would make the variables page-level or session-level. It would depend on whether clients typically have only one booking per session. If they do, you’d need to use page-level variables, otherwise you’d be overwriting session-level ones with a subsequent purchase in the same session. Also the variables would not be associated with a transaction (or with each other) unless you could think of a clever way to do it. Maybe preface each variable with the transaction ID? Then you’d have the data but you’d probably still have to process it outside of GA in Excel or some other tool.

Levy says:

Hi Dorca,

it’s still not clear for me how to setup ecommerce with GTM. Beside the containercode, what code do i have to insert on the thankyou page as the data layer? Just these lines?:

dataLayer = [];

I’ve literally spend a whole day trying to figure out how e-commerce and GTM works. But it’s still not clear to me…Is there a way you could post a step by step guide with clear examples and without skipping important steps?

I would really really appreciate it if you could help me out.

Starting to get desperate after reading hundreds of articles and spending days searching for help on Google :-(

Dorcas Alexander Dorcas Alexander says:

Hi Levy, Please see the ecommerce data layer example in my post above for how the data layer should look. You need to be able to see the pre-rendered code of the page so you know what variables contain the info for transaction ID, transaction total, etc. You will need a developer or you will need to learn how to write code to get the values of those variables into the data layer. There is no “one size fits all” code – it depends on your CMS and your ecommerce setup. Sorry I can’t be more help than that.

james says:


Great post

I am collecting the dataLayer variables for an eCommerce site with multiple products in the basket as above and it is pulling through to the Arrays fine.

In Google Tag Manager how do I get it to refer to the two sku’s in the example as:


I presume I need a piece of looping Javascript…

Speaking from a non-programmer…

Dorcas Alexander Dorcas Alexander says:

Hi James,

Try something like this in a macro (type: custom Javascript), and then call the macro in a tag. Also available here: http://pastie.org/8548549

[Edited because WordPress did not display the code neatly… see the pastie link.]

Denis says:

Great job! There are that many insightful posts in the web on GTM implementation!
I have the following problem: I implemented the GTM code and I’m trying to parse the data to GA (Universal) but I do not get ecommerce data in GA. When I debug the version in GTM it says that the tag fires bug no data gets to GA. Here is how the piece of code looks on the page:

var transactionData = {
‘transactionId': ‘100787’, // Unique transaction identifier, string
‘transactionDate': ‘2013-12-13′, // Date of the transaction, date/string
‘transactionType': ‘purchase’, // Used to indicate what type of transaction has occurred, string
‘transactionAffiliation': ‘name’, // Partner or store, string (remove this line if none)
‘transactionTotal': ‘63.96’, // Total value of the transaction, numeric
‘transactionShipping': ‘0’, // Shipping charge for the transaction, numeric
‘transactionTax': ‘0.00’, // Tax amount for the transaction, numeric
‘transactionPaymentType': ‘Credit Card’, // Payment type (e.g. Credit Card), string
‘transactionCurrency': ‘USD’, // Currency of the transaction, string
‘transactionShippingMethod': ‘name’, // Selected shipping method, string
‘transactionPromoCode': ‘113134’, // Discount or promotion codes used, string (remove this line if none)

‘transactionProducts': [ // List of items purchased in the transaction, array of TransactionProduct objects

‘id': ‘167’, // Product (offer) ID, string
‘name': ‘name’, // Product name, string
‘sku': ‘167’, // Product SKU, string
‘category': ‘name, // Product category, string
‘price': ‘15.99’, // Unit price, numeric
‘currency': ‘USD’, // The currency type of the price, string
‘quantity': 5 // Quantity, integer



I fire the following tag: Tag type:Universal Analytics->Track type:Transaction->Firing rules:1.URL contains checkout_5.cfm (the receipt page with the code) 2. event equals gtm.dom (since I have my transactionData code below the GTM snippet code; I tried without it as well).
Can you help me with this one? Is it something in the code or GTM set up? Thank you very much!

Dorcas Alexander Dorcas Alexander says:

Hi Denis, The major problem is that you’ve declared a variable “transactionData” that is not a valid data structure. This variable looks like an array, which would be enclosed in square brackets [] and not curly braces {}. Unfortunately, simply changing to square brackets will not help you, because then you will push an object to the data layer that buries the variables one level down from where Tag Manager will look for them. The required variables, transactionId and transactionTotal, need to be at the top level of the data layer. Finally, one minor problem is that you are missing a closing quote for the value of your product category. You can track transactions without products, so this problem will not fix the transaction tracking. Good luck!

Scott says:

I’d like to go back to John Castillo’s post. If a site sells 500 items, do we need to manually type in the price, SKU etc for every item sold on the site? How do those areas get populated? Thanks

Dorcas Alexander Dorcas Alexander says:

Hi Scott, You do not manually type in the price, SKU, etc. for every items sold (and how would that even be possible?) – instead you get the values from the back-end variables for price, SKU, etc. You must be able to view the pre-rendered code on the page in order to view those variable names. If you don’t know how to see the pre-rendered code, you need to talk to a developer who is familiar with the CMS for your site. The pre-rendered code needs to be modified to grab the back-end values for the transaction and push them to the rendered code in the data layer. GTM can’t use them until they get to the rendered code on the page.

Tatiana says:


Great post, really helped me understand the essentials!!

I do have one question I can’t seem to find the answer to though…

We’re trying to set up GTM for a website which contains an online tool for employees. All employees have to login before they enter the tool, after login there is a certain parameter which is unique per visitor in the source code, for example:
SAP number:9999

‘SAP number 9999′ is the id we want to retrieve in analytics with GTM.

We want to be able to destinguish how employees (or certain offices) interact with the online tool in analytics. So be able to filter/segment with these “id’s”

I do get we need this “id” to be pushed to the dataLayer;
var dataLayer = [{
‘SAP-number': 9999
//GTM tag

but what would be the best practice to fire a rule/tag? Use a macro to retrieve the value?

Dorcas Alexander Dorcas Alexander says:

Hi Tatiana, Yes, define a macro such as {{SAP-number}} in GTM and then refer to it wherever you would like to pass the value. For example, you might want to send it to GA as the value of a custom variable (or custom dimension in Universal Analytics). Then you would enter the macro {{SAP-number}} under “More settings” in your basic page view tag. I’d make it a session-level custom variable.

Hi Dorcas, this is a real awesome post. I want to use data layer to create custom variables in my Google Analytics. I’ve already installed Google Tag Manager. One issue is I want the data layer to contain tags for my pages, however in some pages there is more than 1 tag. Here is a page w/ 1 tag Daft Punk http://www.stereogum.com/1660361/watch-the-russian-police-choir-perform-get-lucky-at-sochi-winter-olympics-opening-ceremony/video/ and here is a page w/ 2 tags http://www.stereogum.com/1659191/mac-miller-lua-bright-eyes-cover/mp3s/ how would you deal with this?

David says:

Hi Dorcas

thanks for that stunning post. Seems to be best post about GTM and dataLayer.

As many others here I have problem that I cannot figure out (because of lacking coders skills?)

We implemented GTM and within the Google AdWords Conversion Tracking. Works very well so far. Now we want to track the total basket amount with the help of dataLayer elements. The thank you page shows me the following code snippet:

div class=”PlentyFormContainer” id=”PlentyWebPurchaseConfirmationNotice1″>

dataLayer.push({ ‘Price': “15.04” });
dataLayer.push({ ‘PriceinclTaxes': “17.90” });

In GTM I implemented the makro “PriceinclTaxes” which again is implemented in the AdWords tag. It doesnt work though..where could I start troubleshooting?

Kateline says:


Before adding/modifying tags through Tag Manager, should I delete all the tags that I’ve implemented so far (with the help of the developer)? Will the cause errors?

Thank you.

Dorcas Alexander Dorcas Alexander says:

Hi Charlene, Include your tags in an array in the data layer, and then use a macro in GTM to read the array into a delimited string. The macro can then be referenced as the value of your custom variable. One small warning: there is a limit to the number of characters that can be passed to a custom variable in classic GA. The total length of the custom variable key and value should be 128 characters or shorter. Here is an example of the macro structure from some code I wrote to read the ecommerce array of products and return a delimited string of product SKUs: http://pastie.org/8548549. I hope you or your developer can translate this to do something similar with an array of page tags. Just remember to truncate the string if it gets too long.

Dorcas Alexander Dorcas Alexander says:

Hi David, First check your AdWords tag to make sure you are calling the macro name within double quotes, like this: {{PriceinclTaxes}} and make sure there are no typos. Next, use developer’s tools in your browser and check the Console to see whether the data layer actually contains the expected values you think you’ve pushed from your code. You didn’t say whether the AdWords tag was firing but not including your total basket amount, or whether it’s not firing at all. I assume it’s the former and you just need to make sure you connect all the dots by checking the macro definition and tag syntax, as well as the values of the data layer in the Console. See Ian’s tips and my reply at the top of this comment thread, if you’re not familiar with how to view the Console. Good luck!

Dorcas Alexander Dorcas Alexander says:

Hi Kateline, No, you should not delete all your tags before you add tags through Tag Manager. Instead, you should create GA tags that send data to a test property (a different UA number than your current GA property), and all other tags, like those for paid search or affiliate marketing conversion tracking, should be set to fire only in published containers. You’ll find this option in the Advanced settings at the bottom of the tag setup for each tag. When you use the Debug mode, Tag Manager will tell you whether or not that tag would have fired. After you are satisfied that the tags will fire correctly, then you should set up a migration time, during which you simultaneously (1) remove the existing tags from your pages and (2) edit the GA tags in GTM to send data to the UA number for your current GA property. See more information in Google’s official document about Tag Manager migration.

Lindsey says:

Great post, thanks.

I want to set a data layer variable that I can use in rules for tags. We have a lightbox form with no confirmation page. After the user has submitted the form they see an alert with a thank you message. So the page (and GTM container snippet) have already been loaded. At this point we want to do two things, track an event that will be the basis of a GA goal, and add a conversion pixel.

Can I add this line of code to the if statement, before the alert is shown:


or do I need to do something more complicated?

In order to then use this as a rule do I need to create a macro that references the data layer variable?

Dorcas Alexander Dorcas Alexander says:

Hi Lindsey, Yes, you should do all steps exactly as you’ve written them. Just to confirm, those steps are: (1) If XYZ, then push to data layer and show the alert. (2) Create a macro (type: data layer variable) called {{signup}}. (3) Write a rule that fires if {{signup}} equals success, and use that rule to fire all the tags you need in that situation. Thanks for reading!

Alan Myers says:

I am not sure I have a sufficient grasp of the basics of eCommerce GTA setup. I hope you don’t mind what could likely be a really dumb question!

If I can understand the basics (spelled out!) correctly, then I can branch out into more complicated things as they arise, but would you say this is correct for a hotel site?

This would go onto each product page changing the name and price accordingly:

dataLayer = [{
‘name': ‘King Suite’,
‘price': 249.00,
‘currency': ‘USD’,

Then, this would go onto the confirmation page:

dataLayer = [{
‘transactionId': ‘xxxx’, //I’d leave this blank?
‘transactionTotal': xxx.xx, //leave this blank too?
transactionProducts = [{ //These details get filled in automatically,right?
‘name': ‘King Suite’,
‘price': 249.00,
‘quantity': 2
dataLayer.push ({‘transactionProducts':transactionProducts});

Am I even close?

Dorcas Alexander Dorcas Alexander says:

Hi Alan, It’s fine to have the data layer set up as you’ve written it for each product page; however, it is not necessary for GA e-commerce tracking to function. To get e-commerce data into GA, you must have code on the confirmation page… and you cannot leave any of it blank. GA does not fill in the blanks automatically; it needs to know where to look for that information. If you only have one product in your transaction, you may be able to “cheat” a bit and get the transaction details out of the source code of the page. The proper way to do this, though, is to work with the pre-rendered code for the page, and produce the completely filled-in GA code in the final page source. You will almost certainly have to write some extra code (exactly what that code is depends on your CMS) to loop through every product in the transaction and add the product details to the transactionProducts array. All of the transaction info, such as transaction ID, total, etc. should refer to the back-end variable names and the values of those variables will fill in the blanks. If you don’t know how to see your pre-rendered code and view the variables holding this data, you will need a developer’s help.

nzamigo says:

Best GTM dataLayer explanation post I’ve read so far. Thanks.

I am searching for a solution to trigger tags when ajax content is ready. Is that such think like gtm.ajaxComplete or something?

Dorcas Alexander Dorcas Alexander says:

Hi Fiverr, Google Tag Manager recently released a new “history listener” that may help you. The official release notes from March 4 provide a short summary. If you decide to pursue this option, I recommend Simo Ahava’s excellent tutorial on the history listener. Before the history listener was available, I used window.onhashchange for dynamic content tracking. Good luck!

That is brilliant Dorcas! Exactly what I was looking for. I am trying to track Ajax generated content via their IDs.

I will tried this auto event listener out now.
many thanks for pointing me to those articles.

Mark Lilley says:

Hi Dorcas

Thanks for the article, super helpful.

I recently deployed GTM and I’m firing Universal Analytics Ecommerce Tracking on confirmation page based on 2 rules (url = confirmation page and event = trackTransaction). GTM is telling me the tag is firing but no data is present in GA. It has been deployed over a week.

My dataLayer is as below:

dataLayer = [{
‘event': ‘trackTransaction’,
‘transactionId': ‘9868969’,
‘transactionAffiliation': ‘Test’,
‘transactionTotal': 1.00,
‘transactionShipping': 0.00,
‘transactionTax': 0.00,
‘transactionTotalExVatandExShipping': 1.00,
‘transactionProducts': [
‘name': ‘Gift Card’,
‘sku': ‘533d77fc80fc2′,
‘category': ‘Test’,
‘price': 1,
‘quantity': 1

It all looks fine to me, except the ‘null’ value being passed in the transactionProducts array – the developer I’m working with tells me it should be fine?

I assumed it may cause issues with collecting accurate product data within the transaction but shouldn’t stop the transaction being recorded?

Is this what is stopping GA recording any ecommerce data?

Many Thanks


Dorcas Alexander Dorcas Alexander says:

Hi Mark, You are correct that GA should still record transactions even if it does not collect any product data. I can’t see anything in this code that would stop the transaction from being recorded. If GTM says the tag is firing, then the next thing to troubleshoot would be to make sure your transaction tag is set up to send data to the same UA number where you are looking for the data (I know, it sounds obvious). Universal Analytics ecommerce requires the ecommerce.js plugin, which should be automatically included if you are using the Universal Analytics “type” tag in GTM. Are your Universal Analytics pageviews also fired from GTM and, if so, are they working as expected? If not, I’m wondering whether your GA property was set up to process Universal data. The only other thing I can think of to check in Tag Manager would be the settings for your ecommerce tag… do you have a tracker name or domain name set, and does that match the settings for your pageview tag? I’m sorry I can’t be more help.

Jason says:

Hello Dorcas, great information! I have the dataLayer working great, so next step is how to pass those values into an actual 3rd party tracking pixel.

Here’s the code copied from test order success page on Magento EE 1.13.1:

dataLayer = [{
‘transactionId': “1100225280”,
‘transactionDate': “09082014”,
//’transactionType': ”,
//’transactionAffiliation': ”,
‘transactionTotal': 19.99,
‘transactionShipping': 0.0000,
‘transactionTax': 0.0000,
// ‘transactionPaymentType': ”,
‘transactionCurrency': “USD”,
‘transactionShippingMethod': “Shipping Options – Free Shipping”,
‘transactionPromoCode': “thisisatestcode”,

new Date().getTime(),event:’gtm.js’});var f=d.getElementsByTagName(s)[0],

Here’s the pixel tracking code that is currently placed on the Magento EE 1.13 success page.

When the page fires, the values do not get passed into the pixel, so trying to determine if my syntax is correct?


Dorcas Alexander Dorcas Alexander says:

Hi Jason, I can’t see your pixel tracking code, but what you need to do is create a macro for each data layer value you want to pass to that pixel. Then refer to each macro in the pixel tracking code by inserting it with double curly braces. For example, if you want to pass the transaction total to your pixel, then your pixel code should include something like this: mypixel.com?acct=123456&total={{transaction total}}. This assumes that you have created a macro named “transaction total” that looks for the data layer variable transactionTotal. Good luck!

Jef says:

Once we have the dataLayer implemented through GTM, how to we see the custom variables that we have created in Google Analytics?


Dorcas Alexander Dorcas Alexander says:

Hi Jef, After you use GTM to send custom variable data from the data layer to Google Analytics, go to the custom variable reports to view that data (under Audience in the left navigation). If you are sending custom dimensions instead of custom variables, you’ll notice they don’t have their own dedicated reports. Instead you view custom dimensions by choosing them as secondary dimensions in the standard reports, or by creating a custom report where you can make them the primary dimension.

Ted says:

I just implemented GTM and UA on a new client lead-gen site. No eCommerce going on here. I’ve been researching for days as to whether I need to use a data layer at all. What say you, Dorcas?

Dorcas Alexander Dorcas Alexander says:

Hi Ted, You may not need to use a data layer, but you might want to use one. It depends. For example: Every time a new lead submits a form, you can have GTM read information from the thank-you page that follows the form, or you can have GTM read info that your devs push to the data layer upon successful submission of the form. There are at least a couple considerations in favor of using a data layer: (1) the data layer can hold information that wouldn’t otherwise be part of the content of the page, and (2) the data layer can be easier to maintain, especially when the page content (or markup) changes. On the other hand, if your form is fairly simple and you don’t have a lot of information to track, you may be just fine without using a data layer. See my follow-up post for more ideas about how to use the data layer.

Adriaan Boot says:

Hi Dorcas,

Great post, I use it as a reference many times!

I do have a question though.

For the AdWords & affiliate tracking codes I need to communicate the total transaction price excluding VAT. On the confirmation page we’re already communicating ‘transactionTotal’ for the GA E-commerce tracking, but this includes VAT.

What’s the best way to achieve the calculation within Google Tag Manager? I wouldn’t mind using a javascript macro to calculate the price excluding VAT.

Many thanks in advance!


Dorcas Alexander Dorcas Alexander says:

Hi Adriaan, You could use a JavaScript macro to calculate the price excluding VAT, or you (or your dev team) could push that value to the data layer and use a simpler macro to grab it from there. So the same way you’re already pushing transactionTotal to the data layer for use by GA E-commerce, simply push transactionWithoutVAT (or whatever you’d like to name it) instead. I’d prefer to have the information in the data layer rather than calculate it, only to reduce the JavaScript load on the page (however small this bit of script may be, it’s still more script).

Adriaan says:

Hi Dorcas,

I too prefer to work with dataLayer variables. Just got it working through a custom javascript macro!

Thanks again!


Randy says:

Hi Dorcas,

I have as well a question about putting the dataLayer output in a third party pixel.

I have created macro’s for the values that the dataLayer provides as output:

Everything works except for the transactionProducts. When I test my variables with an alert I get all variables working except for transactionProducts.

The output for transactionProducts is [object Object], [object Object].

I can tell from this that the test order has two products, but I can’t get the details. I’ve tried using nested variables as well but I don’t know what I am doing wrong.


Dorcas Alexander Dorcas Alexander says:

Hi Randy, You need to loop through the array of Products and output the details you need, with a macro containing some code like what I’ve pasted in the following link: http://pastie.org/8548549. Hope that helps!