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

By /

October 15, 2013

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 is a Senior Analytics Consultant. Her path to LunaMetrics followed stints in ad agency creative, math, and computer science. Dorcas has a master's degree in language and information technologies from Carnegie Mellon University, where she helped build precursors to a Universal Translator. One of the top-rated tournament Scrabble players in Pennsylvania, Dorcas has an insatiable drive to compete and win.

  • Superclive

    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

      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

    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

      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.

  • http://macreplacementparts.com John Castillo

    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

      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

    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

    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

      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

    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

      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

    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

      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

    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

      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


    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

      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

    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

      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

    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

      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


    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

      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.

  • http://www.linkedin.com/in/charleneiniguez Charlene Dipaola

    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?

    • Dorcas Alexander

      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.

  • David

    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?

    • Dorcas Alexander

      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!

  • Kateline


    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

      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

    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

      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!

  • http://www.pinnacleinternet.com Alan Myers

    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

      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.

  • http://ird.govt.nz nzamigo

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

  • http://fiverrtutorial.com FiverrTutorials

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

  • http://fiverrtutorial.com FiverrTutorials

    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

    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

      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

    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

      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

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


    • Dorcas Alexander

      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

    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

      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

    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

      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

    Hi Dorcas,

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

    Thanks again!


  • http://www.names4ever.nl Randy

    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

      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!

  • Jason Kadlec

    I want to create a trigger that fires when someone is at the /checkout page and a product is in the cart.

    Already, the dataLayer has what I need:

    ecommerce: {
    checkout: {
    actionField: {step1},
    products [
    name: ‘PRODUCT I WANT’
    id: ’70’

    I tried creating a trigger when the page URL contains /checkout

    and the variable ecommerce contains “PRODUCT I WANT” — should that just work – even if the product I’m looking for is nested pretty deep in the ecommerce variable?

    So it’s Trigger Type = Page View.

    Fire this trigger when all these conditions are true.

    Page URL contains “/checkout” +
    ecommerce contains “PRODUCT I WANT”


    • Dorcas Alexander

      Hi Jason,

      You should create a macro/variable in GTM to concatenate the product names into a string and then see if that string contains the name of the product you want.

      First create a macro/variable in GTM that refers to the entire “products” object:

      Name = “ee transaction products” (for enhanced ecommerce transaction products)
      Type = Data Layer Variable
      Data Layer Variable Name = ecommerce.checkout.products
      Data Layer Version = Version 2

      Then create the macro/variable to concatenate the product names:

      Name = “ee product names” (or whatever you want to call it)
      Type = Custom JavaScript
      Custom JavaScript = (see this link: http://pastie.org/10144044)

      Your trigger can then check to see if {{ee product names}} contains the product you want, on the /checkout page.

      • Jason Kadlec

        Woa! I guess Disquss going into my spam… I didn’t see this reply… I can’t wait to try the solution, thank you so much!!

  • Jenna Olovic

    Hi Dorcas, I was wondering what are the possibilities of having a tag firing on URLs that have not been mapped? In what cases would this occur?

    • Dorcas Alexander

      Google Tag Manager fires tags according to the rules/triggers that you create for each tag. If you tell GTM to fire a tag on “all pages” then that tag will fire on every page where you have the GTM code snippet.

  • Demos Flouri

    Hi Dorcas,

    I have to implement a data layer on this website http://www.meadopenfarm.co.uk/ to
    track e-commerce transactions. The shopping process starts here https://meadopenfarm.digitickets.co.uk/tickets#_ga=1.27015549.1193203840.1424692301

    The only thing is, I am struggling to know how the data layer code should look? its literally just to track the name of the ticket and price. That is all we need. Could you assist in showing me how the data layer code should look? can I put this code into GTM of does it have to be placed above the GTM code on the website? and lastly on what page should
    the data layer be placed? I assume the landing page after purchase?

    • Dorcas Alexander

      Hi Demos, You need to place the data layer above the GTM code on the website, on the page after purchase (the “thank you” or confirmation page) where you tell the user their purchase was successfully completed. Even if you only care about the ticket name and price, GA requires certain elements to be sent with your tracking hit. The way those elements should appear in the data layer depends on whether you are using regular ecommerce or enhanced ecommerce. See the following link for regular ecommerce: http://www.simoahava.com/analytics/ecommerce-tips-google-tag-manager/ …and see the following link for enhanced ecommerce: https://developers.google.com/tag-manager/enhanced-ecommerce#purchases

      • Demos Flouri

        Hi, sorry at a risk of sounding stupid, is it simply a case of copying that data layer, for example this one:

        window.dataLayer = window.dataLayer || [];


        ‘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': 1



        even more of a risk of sounding stupid, all these have valued assigned, i.e price 9.99 so I leave the values in or remove and if I remove what goes there as a template value?

        • Dorcas Alexander

          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.

          • Demos Flouri

            oh wow now you have lost me! haha we are only selling tickets that users download, see here https://meadopenfarm.digitickets.co.uk/tickets#_ga=1.27015549.1193203840.1424692301 I am not a developer so struggling to get my head round how the data layer should look.

          • Dorcas Alexander

            Ecommerce is something you probably will need a developer to help you with. You can’t hard-code the price into the data layer on your thank-you page, because you sell tickets with different prices. You need to be able to change the price in the data layer depending on what the user bought, and this requires some programming. See this link for an example of what the simplest data layer should look like, if you only want to track the transaction without any products: http://pastie.org/10189081

          • Demos Flouri

            Thanks so much for you help :-)

  • MP

    Hi.. I am using 3 affiliates and want to attribute sales to respective affiliates during firing of rules. How do i do it

    • Dorcas Alexander

      Hi MP, You will have to have a way to identify the traffic sent by each affiliate, typically by having the affiliate add utm parameters or other query parameters with unique values that tell you which affiliate sent them. Then you can write a rule/trigger that looks in the query portion of the URL for those values.

  • Niamh O’Connell

    Thank you for the article. Really helpful and insightful.

    I’m having an issue creating a Data Layer Variable. On our product detail pages, there is a data layer with the below information. I have tried creating a Data layer variable to extract the product id. I tried this as a Data layer variable and called it productid as the name of the data layer variable: ecommerce.detail.products.id
    But when I try and using this variable in advertising tags, the value came up as null.

    Looking at the data layer information below and the data layer variable I tried to create, is there an obvious reason for why the data layer variable value is returning as null for my advertising tags?

    Data Layer information which is on product page:

    ecommerce: {

    currencyCode: ‘GBP’,

    detail: {products: [{id: ‘4’,

    I really appreciate the help.



    • Dorcas Alexander

      Hi Niamh, The products object is an array or list of products, so you need to tell GTM which product’s id you want, even if there is only one product in the array. The first item of an array has index=0, so use the following to refer to the id of the first product: ecommerce.detail.products[0].id.

      • Niamh O’Connell

        Hi Dorcas

        Thanks for getting back so fast. I tried implementing what you suggested in my data layer variable, but the value of my advertising tag – it’s a Facebook custom audience pixel for view content pages – still appears as [null].

        I’ve named the data layer as productid so I’m using the dynamic variable {{productid}} in my advertising tag.

        Data Layer Variable: ecommerce.detail.products[0].id

        Do you know what else could be the issue?

        I really appreciate the help.



        • Dorcas Alexander

          Try this instead: ecommerce.detail.products.0.id

          • Niamh O’Connell

            Hi Dorcas

            Thanks for replying so fast. For some reason, this didn’t work either.

            When I look at the data layer again, it’s formatted slightly differently to how I originally thought. The data layer looks like the below, so I edited the data layer variable name to look like this: gtm.event.transaction.ecommerce.detail.products.0.id

            But this also didn’t work. The value that is returned when I try the above data layer variable name in my advertising tags is still [null]. I also tried the format products[0] but this also returned [null] as a value.

            Data layer in Google Tag Manager (for product detail pages):
            gtm: {start: XXXXXX, uniqueEventId: XXXXXX},
            event: ‘transaction’,
            ecommerce: {
            currencyCode: ‘GBP’,
            detail: {products: [{id: ‘4’, variant: ”,

          • Dorcas Alexander

            The dots imply a parent relationship, which is one reason why your new reference doesn’t work. You’ve also put a value (‘transaction’) in the reference, which is another reason. The names ‘gtm’, ‘event’, and ‘ecommerce’ are all siblings at the top level of the data layer. The reference ecommerce.detail.products.0.id should return the value ‘4’ so I’m not sure what else we’re missing here. In the Chrome console, I typed a dataLayer.push given what you’ve shown here (I had to fill in the ending), and was able to refer to the id successfully. Are you able to retrieve any values of the data layer or is it perhaps some other syntax error later in the data layer, which you’ve omitted here?

          • Niamh O’Connell

            I am able to retrieve values from the data layer from the final transaction page, but for some reason, not from the product detail page. For example, the parameter {{revenue}} is extracted using this data layer variable and the parameter revenue appears on the final transaction page: ecommerce.purchase.actionField.revenue

            It does sound like it could be a syntax error. Are there any online tools which can help me understand where the syntax error possibly is?

            Thank you so much for your help on this.

          • Dorcas Alexander

            I typically use Chrome developer tools and especially the console tab, which will show errors and warnings for scripts on the page. You can also type modified JavaScript directly into the console to test it, which is what I did earlier when I tried to duplicate your dataLayer code.

Contact Us.


24 S. 18th Street, Suite 100,
Pittsburgh, PA 15203

Follow Us




We'll get back to you
in ONE business day.