Super Guide To Enhanced Ecommerce Tracking via Google Tag Manager [2019]

Enhanced Ecommerce Google Analytics

Last Updated on April 22, 2019 by Ritwik B

Enhanced E-Commerce Reports is one of the most powerful reports in Google Analytics. In this article, you’ll learn to implement the enhanced e-commerce tracking via GTM.

Google Tag Manager simplifies the process of implementation & also it is much more beneficial than google analytics implementation because the same e-commerce data collected in dataLayer can be used in

  • Analytics tools such as mixpanel, amplitude, etc
  • Ad networks such as Facebook, Twitter
  • Remarketing – Dynamic Remarketing in Google or Facebook
  • & so on

 

So it is always scalable to use GTM for tracking purposes.

Here are some of the myths related to Enhanced Ecommerce

  1. Myth: Enhanced E-commerce Tracking can only be implemented on E-commerce Sites.
    Reality: It can be implemented on any site. Most important thing is to understand which e-commerce code populates which metric/dimension.
  2. Myth: We need server-side access to implement Enhanced E-commerce.
    Reality: We can even implement it client-side. But it is recommended to use server-side variables.
  3. Myth: We have to implement each & every code as specified in the GTM Doc.
    Reality: We can implement any portion of the code.
  4. Myth: DataLayer Code placement is important.
    Reality: We can place it anywhere on the page by using custom events to fire e-commerce code.
  5. Myth: It is too difficult to implement enhanced e-commerce
    Reality: Just follow this article & that myth would be busted 😃

 

Let’s start with the framework to follow

Google Analytics Enhanced Ecommerce Framework

Google has defined an ‘ecommerce’ Object containing the following ecommerce measurement objects, namely

  1. impressions
  2. click
  3. detail
  4. add
  5. remove
  6. checkout
  7. checkout_option
  8. purchase
  9. refund
  10. promoView
  11. promoClick

 

To make it easy to understand,

Google has defined different E-commerce Codes for measuring different User Actions. 

 

Every code will populate a particular dimension/metric in the analytics ecommerce report.

The format of the ecommerce code is also easy to visualize as the code starts with

{ ‘ecommerce’ : { USER_ACTION : …. 

 

Eg:

  • { ‘ecommerce’ : { ‘impressions’ : …  represents Product Impressions Data
  • { ‘ecommerce’ : { ‘click’ : … represents Product Click Data
  • { ‘ecommerce’ : { ‘add’ : … represents Add To Cart Data
  • { ‘ecommerce’ : { ‘remove’ : … represents Remove From Cart Data
  • { ‘ecommerce’ : { ‘checkout’ : … represents Checkout Steps Data and so on………..

 

We’ll now be implementing these different blocks of code one by one on different pages.

Make sure to follow this framework or ask your developer to stick it on the wall while implementation process.

 

Enhanced Ecommerce Google Analytics

 

Steps for Google Analytics Enhanced Ecommerce via GTM

Step – 1: Toggle Enhanced e-commerce in Google Analytics (recommended in Test View)

This is a most important step to which lets the analytics show processed & configured in the ecommerce Reports.

Make sure you have a test view created, if not just create a new one. It’s not a good idea to do test tracking in your main (filtered view).

In the Test View, Go To E-commerce Settings > Enable E-commerce > Enable Enhanced E-commerce.

After enabling, you can see the new blank reports in the Conversions > Ecommerce tab.

Enhanced_Ecommerce_Reports in Google Analytics

 

Step – 2: In GTM, Create Google Analytics Event Tag with Enhanced Ecommerce dataLayer Option Checked.

Just create one analytics event tag in google tag manager.

  • Category : ‘Enhanced Ecommerce’
  • Action: ‘{{Event}}’

Enable the dataLayer option in More Settings > Ecommerce.

Save the Tag without Trigger. We’ll be constructing the trigger in below steps.


 

Step – 3 : Implement Product ‘Impressions’ & ‘Click’ Code on Product Listing Pages.

Product listing pages are the pages where products are listed in bulk. These pages may be

  • Search Results pages
  • Product Category Pages
  • Related Product Widget Pages
  • “People who bought this also bought…” widget pages, etc

These ‘impressions’ & ‘click’ code are related & I’ll tell you why.

First, let’s go with ‘impressions’ code.

To implement E-commerce ‘impression’ code follow this logic

  • Populate Product Data in an array of objects. (named productImpressionArray)
  • Pass it in the ecommerce ‘impression’ object.
  • Push ecommerce object to dataLayer.

 

<script>
var window.dataLayer = window.dataLayer || []

//Step-1: Populate product in an array //
var productImpressionArray = [ 
{
'name': 'Product #1',      // Name or ID is required.
'id': '101',
'price': '15.25',
'brand': 'Nike',
'category': 'Shoes',
'variant': 'Gray',
'list': 'Search Results',
'position': 1                  
}, 
{
'name': 'Product #2', // Name or ID is required.
'id': '102',
'price': '22.11',
'brand': 'Puma',
'category': 'Shoes',
'variant': 'Black',
'list': 'Search Results',
'position': 2
}, 
...................
]

//Step - 2: Pass it in ecommerce object //
var ecommerceObject = {
 'ecommerce' : { 'impressions' : productImpressionArray },
'event' : 'productImpressions'                                     //pass custom event
 }

//Step - 3: Push to DataLayer//
dataLayer.push(ecommerceObject)

</script>

 

NOTE: You can place this code anywhere on the site.(as we will fire it on custom event)
If Custom Event is not passed, you’ll have to place it before the tag manager code.

 

Now, let’s do Product ‘click’ code

 

Follow this logic:
  • Use a JS listener to listen for product clicks.
  • Pass clicked product in the array of object, named ‘productClickedArray’. (You can match the ‘id’ of clicked product from previous productImpressionArray variable & fetch the same.)
  • Push ecommerce ‘click’ object to ecommerceObject.
  • Push ecommerceObject to dataLayer.

 

<script>
// Inititalize Click Listener //


// Pass clicked Product in array of object //
var productClickedArray = [{
'name': 'Product #1',             // Name or ID is required.
'id': '1',
'price': '15.25',
'brand': 'Nike',
'category': 'Shoes',
'variant': 'Gray',
'position': 2
}]

//Pass the Product clicked data in ecommerce object //
var ecommerceObject = {
'ecommerce' : { 'click' : 
{ 'products' : productClickedArray, 
  'actionField' : {'list' : 'Search Results' }             // Pass the correct page type in place of 'Search Results'. 
}
},
'event' : 'productClick'                                     //pass custom event
}

//Push the ecommerceObject in dataLayer
dataLayer.push(ecommerceObject)

</script>

 

NOTE: To make sure product click data is passed you can also use the eventCallback function but don’t depend too much on JS.

 

You can now create a new trigger to include regex event named ‘productImpressions|productClick‘. Attach this trigger to previously created analytics event tag.

 

Ecommerce_Tracking_Trigger_-_Custom_Events

Step – 4 : Implement Product ‘Detail’ & ‘Add’ Code on Product Details Pages.

 

Product Details Pages are the pages where we can view product description, select product quantity, variants & also add them to the cart.

 

You can now see that the code logic & format is quite similar.

 

For Product ‘Detail’ Code
  • Pass Product Data in an array of objects. (named productDetailArray)
  • Pass it in the ecommerce ‘detail’ object.
  • Push ecommerce object to dataLayer.

 

<script>
var window.dataLayer = window.dataLayer || []
//Step-1: Pass Product Data in an array of objects //
var productDetailArray= [ 
{
'name': 'Product #1',      // Name or ID is required.
'id': '101',
'price': '15.25',
'brand': 'Nike',
'category': 'Shoes',
'variant': 'Gray'
}
]

//Step - 2: Pass it in ecommerce object //
var ecommerceObject = {
'ecommerce' : { 'detail' : 
{ 'products' : productDetailArray,
  'actionField' : {'list' : 'Related Products'}            
}
},
'event' : 'productDetail'                                   //pass custom event
}

//Step - 3: Push to DataLayer//
dataLayer.push(ecommerceObject)

</script>

 

Modify the previous trigger & add the custom event ‘productDetail’. Now the trigger should look like

‘productImpressions|productClick|productDetail’

 

 

For E-commerce ‘add’ object (Add To Cart),
  • You can use AddToCart callback(ajax success callbacks) if any, to push the product details in dataLayer.
  • Populate the ecommerce ‘add’ object
  • Pass the same in dataLayer

 

It is similar to ecommerce ‘click’ object

 

<script>
// Pass Product added to cart in array of object //
var productAddToCartArray = [{
'name': 'Product #1',             // Name or ID is required.
'id': '1',
'price': '15.25',
'brand': 'Nike',
'category': 'Shoes',
'variant': 'Gray',
'quantity': 1
}]

//Pass the Product Add To Cart data in ecommerce object //
var ecommerceObject = {
 'ecommerce' : { 'add' : 
{ 'products' : productAddToCartArray }, 
'currencyCode' : 'EUR'                                           (Optional) 
},
'event' : 'productAddToCart'                                     //pass custom event
}

//Push the ecommerceObject in dataLayer
dataLayer.push(ecommerceObject)
</script>

 

Modify the Previous Trigger to include ‘productAddToCart’. 

 

If you have option to remove from cart, you can just replace { ‘ecommerce’ : { ‘add’ : ……… to { ‘ecommerce’ : { ‘remove’ : ………   .

 

Rest everything is same as add to cart code.

 

Step – 5 : Implement  ‘Checkout’ Code on Checkout Pages & ‘Purchase’ Code on Transaction Success Page.

 

The implementation of checkout code depends on how many steps you have in the checkout process.
Even if you have one-page checkout (URL not changing) , you can use ajax callbacks to trigger the ‘checkout’ code.

 

You can implement this code when u the er lands on Checkout Page. (Starting Step – 1)

 

Let’s say, ecommerce site checkout flow is
  • Step – 1: User Info
  • Step – 2: Billing Info
  • Step – 3: Shipping
  • Step – 4: Payment Info
  • Step – 5: Confirm

 

So, implement the below code when user lands on User info

 

To implement ecommerce ‘checkout’ code
  • You can use successful callbacks for each step to trigger the code.
  • Pass the products added to cart in the array of objects, named productCheckoutArray.
  • Push the productCheckoutArray data to the ecommerce ‘checkout’ object. 
  • Push the ecommerceObject data to dataLayer.

 

<script>
// Pass Products added to cart in array of object //
var productCheckoutArray = [{
'name': 'Product #1',             // Name or ID is required.
'id': '1',
'price': '15.25',
'brand': 'Nike',
'category': 'Shoes',
'variant': 'Gray',
'quantity': 1
},
{
'name': 'Product #2',             // Name or ID is required.
'id': '2',
'price': '22.10',
'brand': 'Puma',
'category': 'Shoes',
'variant': 'White',
'quantity': 2
}]

//Push the product array data to the ecommerce 'checkout' object. //
var ecommerceObject = {
 'ecommerce' : { 'checkout' : 
{
'products' : productCheckoutArray,
'actionField' : {'step' : 1 }                // Enter Step Number.
}
}
'event' : 'productAddToCart'                                     //pass custom event
}

//Push the ecommerceObject data to dataLayer.//
dataLayer.push(ecommerceObject)
</script>

 

In the above code the important step is the Step Number. It will be reflected in the E-commerce  — > Checkout Behaviour Report in Google Analytics.

 

Checkout_Behaviour_-_Enhanced_Ecommerce_Reports

 

When the user completes the first step & lands on Step – 2: Billing Info, the only change to make in the above code is to change it to step 2.

 

So ‘actionField : {‘step’ : 1 }….  becomes ‘actionField : {‘step’ : 2 } ……

 

You should implement this on all checkout steps.

 

& the final step is the ecommerce ‘purchase’ code.

 

In the final transaction success code, you can use the same product array used for checkout steps.

 

Follow this
  • Pass the same product array of objects obtained in checkout steps in productTransactionArray.
  • Pass transaction info in ‘action field’ object as
    • Transaction/Order ID
    • Revenue. (Should be addition of all products + tax + shipping )
    • tax (optional)
    • shipping (optional)
    • coupon (optional)
    • affiliation (optional)
  • Pass all the above info in ecommerce ‘purchase’ object
  • Pass the ecommerceObject in dataLayer.

 

<script>
// Pass Purchased Products in array of object //
var productPurchasedArray = [{
'name': 'Product #1',             // Name or ID is required.
'id': '1',
'price': '40',
'brand': 'Nike',
'category': 'Shoes',
'variant': 'Gray',
'quantity': 1,
'coupon': 'SUMMER'
},
{
'name': 'Product #2',             // Name or ID is required.
'id': '2',
'price': '20',
'brand': 'Puma',
'category': 'Shoes',
'variant': 'White',
'quantity': 2
}]

var actionField = {
'id': 'T12345',                                            // Transaction ID. Required for purchases and refunds.
'affiliation': 'Online Store',
'revenue': '97',                                      // Total transaction value (incl. tax and shipping)
'tax':'5.5',
'shipping': '11.5',
'coupon': 'SUMMER_SALE' 
}


//Push the product array data to the ecommerce 'purchase' object. //
var ecommerceObject = {
'ecommerce' : {'purchase' : { 
'products' : productPurchasedArray,
'actionField : actionField                //.
}},
'event' : 'transactionSuccess'                                     //pass custom event
}

//Push the ecommerceObject data to dataLayer.//
dataLayer.push(ecommerceObject)
</script>

 

Finally, you have Successfully implemented Enhanced Ecommerce in Google Analytics. But wait…..

 

What About PromoViews, PromoClicks & Refunds?

Let’s talk about promoViews & promoClicks. It is quite similar to ecommerce ‘impressions’ & ‘clicks’ code.

Now it depends on the pages where you implement these promos.

Let’s say you implement it on Product Detail Page.

You can.

  • Pass all the Promos in an array of objects. (named promotionArray)
  • Pass this promo array to ecommerce ‘promoView’ object.
  • Pass ecommerceObject in dataLayer.

 

<script>
// Pass Products added to cart in array of object //
var promotionsViewArray = [{
'name': 'Summer Offer',             // Name or ID is required.
'id': 'SUMMER_SALE',
'creative': 'banner1',
'posiiton': 'slot1'
},
{
'name': 'Free Shipping',             // Name or ID is required.
'id': 'FREE_SHIP',
'creative': 'banner1',
'posiiton': 'slot1'
}]

//Push the product array data to the ecommerce 'checkout' object. //
var ecommerceObject = {
 'ecommerce' : { 'promoView' : 
{
'promotions' : promotionsViewArray
}
}
'event' : 'promoView'                                     //pass custom event
}
//Push the ecommerceObject data to dataLayer.//
dataLayer.push(ecommerceObject)

</script>

 

For PromoClicks, you can implement a click listener follow the same logic as ‘click’ or ‘addtocart’.

 

<script>
// Pass Product added to cart in array of object //
var promoClickArray = [{
'name': 'Summer Sale',             // Name or ID is required.
'id': 'SUMMER_SALE',
'creative': 'Banner1',
'position': 'LeftBanner1'
}]

//Pass the Product Add To Cart data in ecommerce object //
var ecommerceObject = {
 'ecommerce' : { 'promoClick' : 
{ 'promotions' : promoClickArray }
},
'event' : 'promoClick'                                     //pass custom event
 }

//Push the ecommerceObject in dataLayer
dataLayer.push(ecommerceObject)
</script>

 

You can also combine more than one code. Eg:  If the promo is on product detail page along with Impressions., then 3 e-commerce codes will fire simultaneously the promoView, detail & impressions.

<script>
dataLayer.push({
'ecommerce' : { 'promoView' : ........
              { 'detail' : ............
              { 'impressions' : ...........
})

</script>

 

For refunds simply use this code as per gtm docs.  You can change the Transaction/Order ID of refunded data.

dataLayer.push({
  'ecommerce': {
    'refund': {
      'actionField': {'id': '12344'}         // Transaction/Order ID. Required for purchases and refunds.
    }
  }
});

 

The Final Trigger Should include all custom events:

productImpression|productClicks|productDetail|productAddToCart|productCheckout|transactionSuccess

 

https://www.digishuffle.com/wp-content/uploads/2017/12/Enhanced_Ecommerce_GTM.png

 

Make sure to preview all the events before publishing to live view.

 

Important Points

  • You can implement & test the code one by one, if possible.
  • You can start the implementation from the purchase code, then move on to checkout, add to cart & so on….
  • The Transaction & Revenue data in GA will match the backend data 95% of the time. The reason behind it would be a topic for the later post.
  • Feel Free to comment if you implement it successfully or have issues 🙂.

 

 

Other Articles:

Top 10 Ecommerce Tracking Issue Fixes: Is Your Code Not Working? Data Discrepancy? & More…

How To Track Multiple Ecommerce Funnels in Google Analytics (Analytics Hacks)

Bounce Rate Bible: Bounce Rate Benchmarks[2016/2017]

 

Ritwik is a Web Analyst & Product Marketer. He loves to write technical & easy to understand blogs for Marketers & Entrepreneurs. Focused on Google Analytics, Facebook Analytics, Tag Management, Marketing & Automation Scripts & more. Google Certified Professional. A Firm Believer in Teaching -> Learning -> Growing. :)

Comments (19)

  1. rien compris.

  2. Hello Ritwik, thanks a lot for this amazing content ! It is so clear right now ! I just have one question. Does this code must be placed before of after the GTM container code, and do we have to modify anything in the GTM container. Thanks a lot for your help 🙂 Thomas

    1. Thanks Thomas..!! You can place the code anywhere but make sure to have these to the custom HTML code
      1.) ‘var window.dataLayer = window.dataLayer || []’ (line at the top of the code)
      2.) The ‘event’ property in ‘ecommerceObject’.

      Debug the code & check if the values are Ok.

      Ritwik.

      1. Okay, It works for me 🙂 Thanks a lot !

  3. Hello Ritwik, thanks it’s very clear but i’ve got a question, how do you track multiple funnel with enhanced please ?

    Let me explain, i’ve got one funnel with log in or create an account option (see the attach).
    https://uploads.disquscdn.com/images/77347ac995385f956ceaf8068449594bada3bccdcefdf32ffacee22ed367bc16.png

    I will use custom dim (prospect / customer) in order to analyze but i’m not quite sure how GA will send the info for my “already log” or between step 4 and step 6. Cause if i’m already log i can just confirm my billing adress and skip step 5.

    But i want step 5 to be counted.

    Thanks for your help,

    Alan

    1. Hi Alan,

      The enhanced e-commerce funnels are single & sessions based. If you use Session level custom dimension (to segment Prospect/Customer), the only problem is if the (Customer)user logs out after transaction, the whole session gets attributed to (Prospect)Logged Out user. (Source:https://support.google.com/analytics/answer/2709828?hl=en )

      For multiple funnels, I would suggest using event funnels, so the trick is to fire events at every step (Step-1, Step-2, Step-3) with a hit level custom dimension (Prospect / Customer) & then create a column dashboard using the funnel events. (Image below)

      Pros: You can use user & sessions as metrics(Y-axis). Also, upto 9 funnel steps can be added. (they can also be filtered)

      Thanks,
      Ritwik

      https://uploads.disquscdn.com/images/884de5271dae527b6f14fbf60a50d449bdc90bded2dad1e1f4823d1cf2fd3905.png

    1. Hey Ullas,

      Great question..!! Here are some reasons why Events are more useful for ecommerce(or any) tracking.

      1.) Scalable: If you have setup the ecommerce tracking with so much pain, why not send the data to other adnetworks/tools like Facebook, Amplitude/Mixpanel, Google Adwords Conversion, Bing Conversion Pixel, etc.

      Just by creating custom HTML tags & using a ‘Single Regex Event’ trigger, data can be sent to various platforms.

      The docs provided by various tools are only concerned about their own setup. But for businesses, I think its crucial to have a scalable solution with minimum coding/tags/trigger.

      2.) Flexible: If you plan to shut any ecommerce code off, you can just do it by removing the “eventname” from the trigger. (“productImpressions|productClicks|checkout….etc”)

      For large sites, product impressions might hit the daily limit, so it’s better to shut it off.

      3.) Easy Verification: Also, Within a single report, you can verify all the ecommerce event (if working fine) in Top events > Event Category (Ecommerce).

      Thanks,
      Ritwik

  4. Hi Ritwik, thanks for this great article. As I don’t have developers, is it possible to create all these tags using custom HTML tags inside GTM? (thus they won’t appear above the GTM snippet in the code of the page) ? Thanks very much

    1. This script can be fired from a Custom HTML tag in Google Tag Manager and for that the Trigger should either be Dom Ready or Window Loaded.

      1. Thanks very much!

  5. Hi Ritwik,

    This is indeed a good article.

    I have followed the steps as suggested and the tag manager is also reflecting my datalayer variable but the same is not being reflecting in GA hence; i am bit struggling with data reflection issue in GA.

    Can you pls suggest how to resolve this issue.

    Screenshots for your reference:

    https://uploads.disquscdn.com/images/6d9c1a6159b0d5f0b7b469ff611c7a4c2288042f974a3403480d190fc6eb15af.png

    https://uploads.disquscdn.com/images/501034e13bb33c413b9331e910adfa7d3e09a9b47d4b3e3a829ad610c6c3ed02.png

    Thanks !

    1. Hi Avaneet,

      Try entering ‘quantity’ key in product array (name,id,price & quantity). If you have only one product enter ‘quantity’:1.

      Let me know if that works. 🙂

      Thanks,
      Ritwik

      1. Thank you very much, will update you once I implement the same 🙂

      2. hey it worked and it couldn’t be possible without your advise 🙂 Looking forward for more such articles from your end..thanks !

  6. Hi, Thanks for laying out this so well. One question – to track sessions, pageviews on the pages that aren’t covered by the events in your article – do you set up GA pageview tag?

    Thanks again.

    1. Yes, the normal GA pageview tag fired on all pages. 🙂

  7. Ritwik, sorry my ignorance, can I put exactly the same codes you give here or there are parts that must I change, the codes for products, is for all products, for example if have 300 products, must I put 300 codes?.

    1. No.. Don’t put exact code. You will need to modify the product information in the code. So if each page displays 30 products, you will need add 30 product info in the product array.

      Refer this site, where it is mentioned where/how to put the code
      https://enhancedecommerce.appspot.com/

Leave a Reply

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