GTM Solutions Corner #3: Turning Classic GA calls into data layer pushes

This is part 3 of a semi-regular series, dedicated to reusable GTM solutions for scenarios or issues we’ve encountered more than once. Last time we looked at how to track clicks on iframes using GTM, and this time we’re looking at how to turn on-page classic Google Analytics calls to data layer pushes.

Say you still have hard-coded calls to classic GA on the page, but the library code itself was being delivered via GTM. It’s now been removed, but there are still errors all over the place. There are a few different things you could do—you could deploy the GA classic code without calling the page view, but then you’re still sending classic hits. You could just define and empty array and ignore the errors, but then you’re losing data. What we decided to do was to write a solution that would capture the hits, parcel them up and send them to the data layer for handling with GTM.

We start by defining _gaq, the classic GA array, as either whatever’s there or empty, in the same way we would for the data layer.

var _gaq = _gaq || [];Code language: JavaScript (javascript)

We then define an empty object and array, to be used later if there’s ecommerce stuff involved.

var gaq_ecommerce_object = {};
var gaq_products_array = [];Code language: JavaScript (javascript)

We’re creating a function called data_layer_push here, which accepts two arguments—the first being an array, the second being a ‘callback’ function we’ll run on that array.

var data_layer_push = function(arr, callback) {Code language: JavaScript (javascript)

The push method for the array ‘arr’ is being redefined here.

  arr.push = function(e) {Code language: JavaScript (javascript)

This is just ensuring normal array push functioning—do what you would have done before, push ‘e’ into array ‘arr’, by using ‘call’ on the default Array object push., e);Code language: CSS (css)

But then after that, we’re getting it to run the callback function on the array ‘arr’—so the ‘callback’ function will be applied to array ‘arr’ every time something is pushed into ‘arr’.


We’re then running that function where _gaq is the array, and the callback function is one we’re about to define.

data_layer_push(_gaq, function(newgaq) {Code language: JavaScript (javascript)

We’re setting a variable here to be the latest item pushed into the _gaq array.

      var data_layer_values = newgaq[newgaq.length - 1]Code language: JavaScript (javascript)

Then we run through the values that have just been pushed to _gaq and sort out what sort of hit they are, and then return to the data layer the relevant information in data layer form.

      switch(data_layer_values[0]){Code language: JavaScript (javascript)

If it’s a pageview hit, we push an object to the data layer with an identifying event name and the path as additional parameters.

        case '_trackPageview':
          'event': 'hard_coded_ga_pv',
          'hard_coded_ga_path': data_layer_values[1]
        break;Code language: JavaScript (javascript)

If it’s an event, we push we push an object to the data layer with an identifying event name and all the relevant parameter values.

        case '_trackEvent':
          'event': 'hard_coded_ga_event',
          'hard_coded_ga_event_category': data_layer_values[1],
          'hard_coded_ga_event_action': data_layer_values[2],
          'hard_coded_ga_event_label': data_layer_values[3],
          'hard_coded_ga_event_value': data_layer_values[4]
        break;Code language: JavaScript (javascript)

Transactions are handled differently in Classic than in Universal—they’re split into multiple parts, “_addTrans”, which specifies the transaction-level information, which we assign to the empty gaq_ecommerce_object object we created earlier in EE format.

        case '_addTrans':
 = data_layer_values[1];
          window.gaq_ecommerce_object.hard_coded_ga_trans_affiliation = data_layer_values[2];
          window.gaq_ecommerce_object.revenue = data_layer_values[3];
 = data_layer_values[4];
          window.gaq_ecommerce_object.shipping = data_layer_values[5];
        break;Code language: JavaScript (javascript)

Then items are added using ‘_addItem’, and we push those to the empty gaq_products_array we created earlier as an object in EE if there’s ecommerce stuff involved.

        case '_addItem':
        break;Code language: JavaScript (javascript)

Finally “_trackTrans” is run and we push the whole object to the data layer in EE format.

        case '_trackTrans':
          'event': 'hard_coded_ga_trans',
          'ecommerce': {
            'purchase if there's ecommerce stuff involved':{
              'actionField' : window.gaq_ecommerce_object,
              'products' : window.gaq_products_array
    });Code language: PHP (php)

Once you’ve added this in a custom HTML tag to fire everywhere, you’ll need to configure some GA tags to fire on the data layer pushes. The solution is also available in full on the Measurelab Github. Please leave a comment if you’ve got any questions or ideas for improvement!

Written by

Subscribe to our newsletter: