Easier Enhanced Ecommerce Product & Promo Tracking

Google Analytics - Shopping Behavior Analysis

Implementing Google Analytics Enhanced Ecommerce can be complicated, and especially product and promo (internal banner) tracking can be tricky. The “concept” in this blog post addresses a solution to some common implementation and tracking problems:

  • Consistent naming and values across impressions, clicks and add to cart.
  • HTTP Request Limit for impression tracking. The limit for a HTTP request to the Google Analytics endpoint is 8Kb (or more exactly 8192 bytes). If the number of objects (products) in the array is larger than your defined number, let’s say 35, and a visitor has selected to show 100 products, this solution will automatically send the data in 3 hits to avoid hitting the 8Kb limit.
  • If there are many different modules on a page, it can be problematic to integrate data for all those modules into 1 impression tracking script. Modules in this context can be Bestsellers, Related Products, Other Customers Also Bought, Newly arrived, category page etc.

About this Product & Promo Tracking concept

Most of the problems listed above are solved using javascript. To use this concept you have to use Google Tag Managerand some of the code is jQuery. Althoug scripts in this article is very custom, it’s based on the Google Tag Manager Enhanced Ecommerce documentation.

The reason for calling this for a “concept” is because although some of the code can more or less just be copied and used as it is, you will still have to do some server side programming and adapt the concept to your needs.

The key to success is pid

In my scripts you will find a variable called pid. This is a key that we use for all click tracking (add to cart, product click, promo click, add to wishlist and add to compare). This key must be unique. If for example Product A is found in 2 different modules on the same page (ex. listed both in Related Products and Other Customers Also Bought), pid must be different in those two modules.

To create a unique pid you can ex. use the database ID for the product + part of the module name. Let’s say the database ID for Product A is 123. Then pid could be Rel123 in the Related Products module, and Oth123 in the Other Customers Also Bought module.

Impression data implementation

This concept is using the JavaScript Array push() Method to overcome the problem with integrating data from different modules into one Enhanced Ecommerce Impression tracking script.

Step 1 – define your product and promo array

Products and promo (internal banners) will be in 2 different arrays called product and promo. Add the script above before your global Google Tag Manager script, ex. before </head>.

Product Impression script

The script example below should be implemented into the different product modules. The code below is an example code for the “Bestsellers” module.

As mentioned, it’s vital that pid is unique since all product click tracking will use data from the product impression script.

Promo/banner Impression code

The script example below should be implemented into the different internal banner modules.

Promo/internal banner must also have a unique pid.

Enhanced Ecommerce Impression tracking scripts

Generic Impression tracking script

The generic impression tracking script should be added to all pages that has product data except the product detail page.

This script should be implemented at the end of your page (before </body>). I have implemented it like this since I also send other page type specific data with this script.

You can implement this script in a Custom HTML tag in Google Tag Manager if you like. If you do that, the Trigger should either be Dom Ready  or Window Loaded, or you can create a more advanced Trigger that checks if the product or promo array contains data. I haven’t tested this.

Impression tracking script for Product Detail Page

This script should be added to the product detail page.

This script should be implemented at the end of your page (before </body>). I have implemented it like this since I also send other page type specific data with this script.

The script doesn’t check for number of objects in the product or promo array since this is normally not necessary on a product page.

Tagging of Buttons and Links

All product and promo links, and all buttons (add to cart, wishlist and compare) have to be tagged in some way. I’m using data attributes in this example. This concept requires 2 different data attributes:

  1. data-pid: This attribute has the unique ID for the product or banner.
  2. data-type: This attribute tells the script what kind of click this is:
    1. link
    2. cart
    3. promo
    4. wishlist
    5. compare

The HTML example below demonstrates this tagging.

Code for tracking Add to Cart, Product & Promo Clicks, Add to Wishlist and Add to Compare

This script takes the pid data attribute value, and matches it against the ecomm array. If a match is found, data about the product or internal banner will be sent to Google Analytics as either Add to Cart, Product Click, Promo Click, Add to Wishlist or Add to Compare.

This script should be implemented on all pages that has product data. You can add this script to a Custom HTML Tag in Google Tag Manager if you like.

Widening product data with Dimensions or Metrics

If you want to widen your product data with either dimensions or metrics, there is one caveat you have to be aware of.

Let’s say you want to track product discount. You want to track the discount in percentage as a dimension, but you also want to track the amount as a metric. The dimension should be sent both with impression and add to cart, but the metric should only be sent with add to cart. Your Discount Percentage dimension is in your Google Analytics setup dimension1, and your Discount Amount metric is metric1.

If you want to send the dimension or metric data with the impression, use the dimension or metric variable names from Google Analytics, ex. dimension1 and metric1. If you don’t want to send the data with the impression, call the variable something else.

In the code example below, the discount in percentage (25) will be sent with the impression since it’s named dimension1. The discount amount (24.40) will not be sent since it’s named discount.

To send the discount in both percentage and amount with Add to Cart, you will have to change the Add to Cart code into this:

Google Tag Manager setup

Google Tag Manager Variables

Add the Variables relevant for your e-Commerce store to Google Tag Manager.

Variable NameData Layer Variable NameComment
productNamenameFor Wishlist & Compare tracking
productListlistFor Wishlist & Compare tracking
productListClickecommerce.click.actionField.listFor tracking product clicks as GA Events also
productNameClickecommerce.click.products.0.nameFor tracking product clicks as GA Events also
productQuantityquantityFor Wishlist & Compare tracking
promoClickNameecommerce.promoClick.promotions.0.nameFor tracking promo clicks as GA Events also
promoCreativeecommerce.promoClick.promotions.0.creativeFor tracking promo clicks as GA Events also
addToCartListecommerce.add.actionField.listTrack Add to Cart as GA Events as well
addToCartNameecommerce.add.products.0.nameTrack Add to Cart as GA Events as well
addToCartQuantityecommerce.add.products.0.quantityTrack Add to Cart as GA Events as well

Google Tag Manager Event Triggers

Add the Event Triggers that is relevant for your e-Commerce store to Google Tag Manager.

Trigger NameEvent NameComment
addToCartaddToCartAdd to Cart trigger
addToCompareaddToCompareAdd to Compare trigger
addToWishlistaddToWishlistAdd to Wishlist trigger
impressionimpressionImpression tracking trigger
productClickproductClickProduct Click trigger
promoClickpromoClickPromo/banner Click trigger

Google Tag Manager Tags setup

Enhanced Ecommerce Impression tracking

WhatSettingComment
Tag TypeUniversal Analytics
Track TypeEvent
Enable Enhanced Ecommerce FeaturesTrue
Use Data LayerTrue
Triggerimpression
Event Category{{eventCategory}}
Event Action{{eventAction}}
Event LabelLeave empty
Event ValueLeave empty
Non-Interaction HitTrueGA Event that doesn't affect Bounce Rate

Add to Cart tracking

WhatSettingComment
Tag TypeUniversal Analytics
Track TypeEvent
Enable Enhanced Ecommerce FeaturesTrue
Use Data LayerTrue
TriggeraddToCart
Event CategoryAdd to Cart
Event Action{{addToCartList}}Track Enhanced List Name as Action
Event Label{{addToCartName}}Track Product Name as Label
Event Value{{addToCartQuantity}}Track Number of products added to cart as Value
Non-Interaction HitFalse

Product Click tracking

WhatSettingComment
Tag TypeUniversal Analytics
Track TypeEvent
Enable Enhanced Ecommerce FeaturesTrue
Use Data LayerTrue
TriggerproductClick
Event CategoryProduct Click
Event Action{{productListClick}}Track Enhanced List Name as Action
Event Label{{productNameClick}}Track Product Name as Label
Event ValueLeave empty
Non-Interaction HitFalse

Promo (Internal banner) Click tracking

WhatSettingComment
Tag TypeUniversal Analytics
Track TypeEvent
Enable Enhanced Ecommerce FeaturesTrue
Use Data LayerTrue
TriggerpromoClick
Event CategoryInternal Banner
Event Action{{promoClickName}}Track Promo Name as Action
Event Label{{promoCreative}}Track Creative as Label. If you don't send this data, leave empty.
Event ValueLeave empty
Non-Interaction HitFalse

Add to Wishlist tracking

WhatSettingComment
Tag TypeUniversal Analytics
Track TypeEvent
Enable Enhanced Ecommerce FeaturesFalse
TriggeraddToWishlist
Event CategoryAdd to Wishlist
Event Action{{productList}}Track Enhanced List Name as Action
Event Label{{productName}}Track Product Name as Label
Event Value{{productQuantity}}Track Number of products added to Wishlist as Value
Non-Interaction HitFalse

Add to Compare tracking

WhatSettingComment
Tag TypeUniversal Analytics
Track TypeEvent
Enable Enhanced Ecommerce FeaturesFalse
TriggeraddToCompare
Event CategoryAdd to Compare
Event Action{{productList}}Track Enhanced List Name as Action
Event Label{{productName}}Track Product Name as Label
Event Value{{productQuantity}}Track Number of products added to Compare as Value
Non-Interaction HitFalse

Some final words

All tracking described in this blog post is done using Google Analytics Events. Especially impression tracking will increase the number of hits to your Google Analytics account. Although I haven’t experienced any problems with this method, you should be aware of the Google Analytics Collection Limits and Quotas.

If you have solved the problems described in the beginning of this blog post in a different way, or if you think that the concept or scripts could be improved (I’m not a programmer), feel free to add a comment.

17 Comments on "Easier Enhanced Ecommerce Product & Promo Tracking"

  1. Hello, thanks for great article !
    I have a problem that bother me several days.
    There is a pic ( ),
    This pic’s data-pid and data-type are added after mouseover event.
    And the code in this article ( $(‘[data-pid][data-type]’).on(‘click’, function( event ){ )
    can’t detect when click pic.
    Is that the reason data-pid and data-type aren’t set before dom ready?
    And what can I do ..

    Thanks

    • Hi Enix

      If I understand your problem correctly, on the image there is a mouseover event that hinders the click tracking, is that correct?

      I can’t promise anything, but could you drop your code as a comment, and I could try to take a look.

      “Is that the reason data-pid and data-type aren’t set before dom ready?”
      I’m not sure I understand this question.

      Eivind

  2. Hi Eivind,

    Great post! I have two quick questions:

    1. Under Google Tag Manager Variables shouldn’t you also include “eventCategory” and “eventAction”?

    2. Under Promo (Internal banner) Click tracking shouldn’t the Event be “promoClick” instead of “productClick”?

    • Eivind Savio | May 19, 2016 at 10:40 pm | Reply

      Hi Andrew

      Thanks for your feedback.

      1. No. If you look at the Tag Setup part you will see that I use ex. {{addToCartList}} as Event Action.
      2. You are correct. Great spotted!

      There is one more thing I should have added to this blog post. I doesn’t use “list” for product detail page (and I don’t think you should), which means that you will get “undefined” Event Action for products added to cart from the product page. That is of course not correct. I will try to update the blog post soon to the latest version of my setup.

      Regards,
      Eivind

      • Hi Eivind,

        Great article!
        I implemented it this way and GTM is complaining that I must have variables for {{eventCategory}} and {{eventAction}}

        Am I missing something here?

        • Eivind Savio | July 30, 2016 at 5:35 pm | Reply

          Hi Andrei

          If I understand your problem correctly I think you have forgotten to create those Data Layer Variables in your GTM setup. You have to create 1 Data Layer Variable called eventCategory and 1 Data Layer Variable called eventAction.

          Regards,
          Eivind

  3. Hey Eivind,

    I’ve followed this post with great interest and spent the weekend implementing, debugging and generally just playing with the various settings in GTM – thank you for putting this together! As a relative newbie to GTM (coming from the likes of Adobe Analytics, Tealium etc) I found this post incredibly useful.

    One question I did have for you – specifically regarding the Add To Cart functionality.

    On my test website, I have a single button that adds a bundle of products to the cart with a single click (it adds a product and an accessory). I want to keep them split this way and not pass a Bundle PID or Bundled product into GTM/GA.

    How would you recommend I change the code so this happens?

    Thanks again!
    R

    • Alon Mizrahi | July 25, 2016 at 8:07 am | Reply

      I would implement the data-pid with multiple ids splitted by some char, and before entering the case function, check whether there are multiple pids. If so, push by a for loop depending on the size of the split.
      Hope that give you some sense.

  4. Alon Mizrahi | July 25, 2016 at 8:02 am | Reply

    That is a great article! I wonder of it can be simplified to adjuat into angularjs, Without jquery.

  5. Trying your Impression tracking scripts but didn’t work at all.
    Is there any update maybe on 2017?

    • I have this method running on ecommere stores without problem. However, sometimes I have used a different approach, and that is to split the ecommerce object in GTM instead.

  6. Hi Eivind,
    Nice post,very clear steps of GTM implementation.
    Just wanted to know why did you opted the product Impressions as Events instead of Pageview, even Enhanced Ecommerce (UA) Developer Guide suggests to use product Impressions as pageviews.

    • Eivind Savio | March 22, 2018 at 9:12 pm | Reply

      Hi Ullas

      There are at least 4 reasons for this:
      1. As mentioned in the blog post, the limit for a HTTP request to the Google Analytics endpoint is 8Kb. If the HTTP request is above 8Kb, data will not be sent to GA at all (including your pageviews). In cases like this you will have to split the object, and then you can’t use a pageview.
      2. Using GTM Event triggers gives you more control, and you will not have a setup where sometimes a regular pageview sends the Enhanced Data, and sometimes not. This will lead you into trouble most likely.
      3. Very often data isn’t available on pageview. You could of course use a DOM Ready trigger instead, but this doesn’t help you with point 1.
      4. Often you send the data to other places than Google Analytics. Ex. like demonstrated with this method:
      https://www.savio.no/google-tag-manager/generic-string-enhanced-ecommerce-product-values-gtm
      If you base everything on GTM Event Triggers for sending Ecommerce Data, you will be more prepared for other use cases as well.

      Regards,
      Eivind

  7. Hi Savio, thanks for sharing.
    I think the question in the first comment is that possible to refer a gtm variable in jquery.
    I’m trying myself to do something like $({{customvlookup}}).on(‘click’, function( event )

    But it doesn t work. Is that possible please ?

    The main idea is to use jquery with a vlookup to handle all my click event.

    Something like :
    $(‘vlookupdivelement’).click(function() {
    dataLayer.push({
    ‘event’: ‘Fire Event GA’,
    ‘event.category’: ‘{{vlookupcat}}’,
    And so on

    I doesn t work. Maybe i miss something. Could you help me please ? I’m new in gtm.

    Thanks a lot,

    Alan

  8. Hi Eivind,
    I am sending Product list views (impressions). I have many of them on a single page like 200 at once. I am sending them in chunks like this

    while (impressionProducts.length > 0) {
    var impressionChunks = impressionProducts.splice(0, 35);
    dataLayer.push({
    'ecommerce': {
    'currencyCode': currencyCode, // Local currency is optional.
    'impressions': impressionChunks
    },
    'event': 'impressionPush', // GTM Event for Impression tracking
    'eventCategory': 'Ecommerce', 'eventAction': 'Product Impression'
    });
    }

    But this is not sending all of them. It only sends last chunk of impressions. Could you please suggest what I am doing wrong

  9. Hello Eivind, this is a great post.

    I have a question. At the purchase stage, how do you track product position and list? Should we use cookies or an other method? Because at Analytics list view I see the products but purchases has no list or position data.

    Regards,
    Vassilis.

    • Hi

      For purchase stage, you don’t track product position and list.
      Google Analytics will automatically attribute list clicks to sales.

      Regards,
      Eivind

Leave a comment

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.