Enhanced Ecommerce is a very nice improvement to the pretty lame, transaction-based Ecommerce tracking in Universal Analytics. Instead of staring blindly at what happens on a receipt page, Enhanced Ecommerce expands your entire webstore into one large funnel labelled “Shopping Behavior”, and you’re able to zoom in on the Checkout funnel as well. Also, the addition of product-scoped tracking is incredibly useful, and it’s enabled us to think of any asset (our content, for example) on our site as something we could track through the Enhanced Ecommerce reports.

Tracking Enhanced Ecommerce through Google Tag Manager is pretty straight-forward. It boils down to a properly formatted Data Layer, which GTM will then use to send the hits to Google Analytics.

Now, the thing with the Data Layer is that you want to try to make it as platform-agnostic as possible. I mean, it doesn’t make sense to encode objects in the Data Layer for one platform’s needs alone, as a complex object syntax will make it quite difficult to reuse the same information for platforms which might have a completely different syntax.

Enhanced Ecommerce requires a very specific syntax in the Data Layer object. In addition to this, there are some very ill-designed, Google Analytics -specific, customizations you will need to implement if you want to utilize the Data Layer for Enhanced Ecommerce. An example of these customizations would be adding product-scoped Custom Dimensions and/or Metrics to the payload.

X

The Simmer Newsletter

Subscribe to the Simmer newsletter to get the latest news and content from Simo Ahava into your email inbox!

Product-scoped Custom Definitions the GTM way

Here’s an example. Let’s send a product-scoped Custom Dimension with our “Add To Cart” action. The Custom Dimension will tell whether the product is a promotion or a regular item. The code you’d need in your Data Layer would look like this:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event' : 'addToCart',
  'ecommerce' : {
    'add' : {
      'products' : [{
        'id' : '12345',
        'name' : 'ACME Flame Thrower',
        'dimension2' : 'Promotion'
      }]
    }
  }
});

This hit would prepare the Data Layer for an “Add To Cart” action, where the value ‘Promotion’ is sent to GA to Custom Dimension index 2.

Now, this would be fine in a perfect world, where you have an incredibly agile cooperation model with your own developers and with the developers of third-party platforms you have on your site. If the Custom Dimension should change, you can just quickly ask them to push an update to the Data Layer, where dimension2 is replaced with the new index number.

However, this is rarely the reality. Also, all other parts of the Data Layer object above can be easily reused in other platforms, and the key names (e.g. ‘id’, ‘name’) are self-explanatory, but ‘dimension2’ just won’t ring a bell with platforms that do not think in terms of dimensions. So we’ve taken an agnostic Data Layer and turned it very proprietary, respecting the needs of one single platform (Google Analytics) alone.

Use a Custom JavaScript Variable instead

Turns out that you can use a Custom JavaScript Variable to push Enhanced Ecommerce payloads to Google Analytics as well:

We can thus use a Custom JavaScript Variable to do all the platform-specific customizations, and we can leave our Data Layer as generic as possible.

So, let’s assume we still have the Data Layer in its normal state, but without the ‘dimension2’ key in it:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event' : 'addToCart',
  'ecommerce' : {
    'add' : {
      'products' : [{
        'id' : '12345',
        'name' : 'ACME Flame Thrower'
      }]
    }
  }
});

We want to fire the GA Tag, which sends the Add To Cart action to Google Analytics, when this payload is pushed into Data Layer, but we want to also add the Custom Dimension to the payload without having to modify the dataLayer.push() method.

To make this happen, you will first need to create a new Data Layer Variable, which returns the ‘ecommerce’ payload:

This Variable returns the value of the ‘ecommerce’ key in the data model. Note, I’m using Version 1 of the Data Layer, because that’s what GTM uses for Enhanced Ecommerce. It protects your Enhanced Ecommerce objects from something called a recursive merge, which would result in each ‘ecommerce’ payload persisting all the previous objects, e.g. ‘promotions’ and ‘impressions’ in each hit, resulting in a lot of extra, invalid information being sent to Google Analytics.

Once you have that Variable in place, you will need the actual Custom JavaScript Variable, which I’ve named {{EEC - AddToCart With Dimension}}.

function() {
  var dIndx = '2'; // This is the Custom Dimension Index
  // Make a shallow copy of the ecommerce object
  var ecom = JSON.parse(JSON.stringify({{DLV - ecommerce}}));
  var ecomAddProducts = ecom['add']['products'];
  ecomAddProducts[0]['dimension' + dIndx] = ecomAddProducts[0]['id'] === '12345' ? 'Promotion' : 'Regular';
  return {'ecommerce' : {'add' : {'products' : ecomAddProducts}}};
}

On the first line, you define the Custom Dimension index. Next, you create a little placeholder variable for the ‘products’ key in the {'ecommerce' : {'add' : {}} } object.

Next, you’ll make a copy of the original {{DLV - ecommerce}} variable by using the JSON.parse(JSON.stringify(obj)) trick. This is to prevent multiple iterations of the Custom JS variable from inadvertently running whatever modifications you do over and over again on the source variable, resulting in unexpected results.

Then, you basically check if the first (only) product in the ‘products’ Array has ID ‘12345’. If it does, you add the Custom Dimension key ‘dimension2’ into the product object with the value ‘Promotion’. If the ID is something else, the dimension value is set to ‘Regular’.

You can be very creative here, fetching valid IDs from a Lookup Table, for example. The key thing is to return a complete ‘ecommerce’ object in the Custom JavaScript Variable. That’s how GTM works. If you don’t return a syntactically valid ‘ecommerce’ object, Enhanced Ecommerce will not work.

Just to clarify: a valid ‘ecommerce’ object means that the payload needs to be crafted according to how you would create the Data Layer object. A good place to find more information is in the developer guide for the Enhanced Ecommerce Data Layer.

Things to keep in mind

To make the Custom JavaScript Variable method work with GTM, you will need to remember the following, easy steps:

  1. Use a Custom JavaScript Variable which returns a valid {'ecommerce' : {}} object

  2. Uncheck Use data layer in your GA Tag settings

  3. Select the variable you created in (1) in the drop-down menu labelled Read data from variable

That’s all you need to change. Your Tag should still fire on the Custom Event Trigger for Event Name: addToCart. This time, however, instead of using the Data Layer ‘ecommerce’ object, it uses the ‘ecommerce’ object returned by your Custom JavaScript Variable.

Use cases

The best way to use the Custom JavaScript Variable has already been mentioned a few times in this article. Use the Custom JS Variable to turn a generic Data Layer object into a Google Analytics -specific payload. This means that you can ask your developers to implement a very generic Ecommerce payload with the “Add To Cart” action. This makes it easier for other platforms to tap into the data, as you don’t need to know how Google Analytics works to be able to understand how the object is built.

Another good use case is for product-specific Custom Dimensions and Metrics, which I’ve showed an example of in this article. It doesn’t really make sense to add those to the Data Layer, as dimension and metrics can change, and adding keys that are only used by one platform is a bit counter-intuitive.

I’ve found myself using the Custom JavaScript Variable method in almost all the implementations I work with, even if the Data Layer ‘ecommerce’ object is well-formed to begin with. I like the idea that I can flexibly change the payload on a whim, without having to update the Data Layer.

Naturally, if the changes are fundamental, such as product names changing or IDs receiving a new format, you will want to update the on-page Data Layer instead of encoding these changes in your Custom JavaScript Variable. But the Custom JavaScript Variable is perfect for implementing platform-specific payload syntax in your Ecommerce tracking.

Have you got some other use cases for the Custom JavaScript Variable method? Please, do share!