The Blog

Controlling Tag Firing Order with Google Tag Manager

Google Tag Manager Secrets Revealed

Google announced the release of Google Tag Manager (GTM) on October 1, 2012. Since that time, Cardinal Path has been fortunate enough to put it through its paces, as well as to compare it alongside other commercial tag management systems. Our friend Justin Cutroni keeps a great list of Commercial TMS systems in use today.

If you’re currently evaluating the best TMS for your organization, Cardinal Path can help you determine which one is best for you. Contact us for more information.

Read The Documentation

Like most Google products, and unlike its competitors, Google Tag Manager is free. In addition to being free, GTM is a very powerful Tag Management System with version control built in, as well as a unique testing feature called Preview & Debug, that shows you, in real-time, which tags will load and fire – before you actually publish the tag. This alone can be a huge time saver and is a fast and easy way to catch errors before corrupting your analytics data due to a simple mistake.

Our colleagues at Moz.com once complained, “There is no manual,” concealing GTM’s power from all but the most adventurous of web analysts and javascript-coding marketers.

While there may be no comprehensive manual for GTM, there are some Google Tag Manager help topics in the Support center, as well as a public Google Tag Manager forum for asking and answering questions from other GTM users around the globe.

Leveraging Google Tag Manager

For one of our recent deployments, our client wanted to implement Google Tag Manager across their portfolio of 30+ domains, with 60+ subdomains worldwide. Most of these domains share some tracking code from specific vendors, but each domain and subdomain had its own individual tracking requirements as well.

One of the first things we realized was that in order to make the most use of Google Tag Manager, we needed a strategy to leverage its best features, and that meant migrating several of the client’s existing Javascript tags to GTM from the current static implementation embedded in their site template.

Challenges

We were given a complicated set of requirements. We hoped that GTM could be used to fulfill all of them, but we weren’t sure at first.

Our main goals were to be able to use GTM to control the tags that fired on each domain, while at the same time, we wanted to be able to optimize the code in GTM in such a way as to not repeat (copy-paste) any code. The theory here is that Google Tag Manager loads all code on all sites, it only fires certain tags, and we wanted to minimize the amount of code loading on every domain to keep load times at the absolute minimum.

You Cannot Control Tag Load Order

We knew from the outset of this deployment that one of our biggest challenges in making the most use of Google Tag Manager was going to be the inability to control tag load order. According to their own support document, Google states that within Google Tag Manager

“You cannot control the order or precedence of your tags.”

This is absolutely true as it pertains to when tags load. Undaunted, we created some test profiles and began experimenting with Macros, Rules, and Custom Events. What we found may seem surprising, and appears at first to contradict Google Support’s very black-and-white answer.

You Can Control Tag Firing Order

While you cannot control the order in which tags load, you can control the order in which tags fire. This is a subtle, but important point. In reality, it doesn’t really matter what order a bunch of async tags load. What matters most is the ability to control the script execution order, and that is exactly what Google provides with the concept of events, already built into GTM.

To control the tag firing order of your tags within Google Tag Manager is relatively straightforward, once you understand how GTM defines and uses Custom Events.

One note here is that all of our tags inside GTM are of type “Custom HTML Tag” which means we’re writing our own Javascript for each tag. You can’t control the load order or the firing order of the built-in tag types other than Custom HTML Tag because it requires adding one extra line of Javascript, as you’ll see later on down this post.

After a quick glance at the GTM support documentation, you may be led to believe that GTM doesn’t even support events. GTM does support events, however the information on it is a bit buried under the Macros section of the help, and they don’t give you much in the way of examples.

In short, you can define a Macro in GTM, with a type of Custom Event. Your event can be designed to fire at any point in your code, and you can name it anything you like. The event can be fired from other Javascript code on your site template, or it can be fired from other tags loaded inside your GTM container tag.

Steps To Reproduce

Let’s say you have three tags to load in your GTM container, and you want Tag A to load first, followed by Tag B, and finally, Tag C.

If you’re used to procedural code that flows in a top-down fashion, this should seem very straightforward, but due to the way that Google Tag Manager loads all three of those tags asynchronously, we cannot know at runtime which tag will be downloaded and executed first.

The secret is to leverage the dataLayer and events built into GTM.

The default rule in GTM just says to fire on “All Pages” and uses the following rule as a definition:

{{url}} matches RegeEx .*

Now, this may be a minor distinction, and I haven’t done thorough testing to know for sure, but I stumbled on a particularly useful event on the Google Tag Manager Support Site.

To define a tag such that it fires when the DOM is ready, add a “event equals gtm.dom” condition to the firing rule.

Knowing that we’re dealing with sub-second timing at the low level execution of Javascript in a modern browser across a collection of script tags all loading asynchronously, I figured we should use the {{event}} equals gtm.dom as our “starting event”, since it should fire a few dozen microseconds later than the default rule of

{{url}} matches RegEx .*

So, since we wanted Tag A to load first, we started by using

{{event}} equals "gtm.dom"

as the firing rule for Tag A.

We’re getting to the secret

At the end of your Tag A, add the following code…

dataLayer.push({'event':'doneWithTagA'});

Next, move on to Tag B, also of type Custom HTML Tag, and at the end of the Javascript there, right above the closing </script> tag, add the following code:

dataLayer.push({'event':'doneWithTagB'});

Now, here’s the magic.

Set Tag B’s firing rule to be:

{{event}} equals 'doneWithTagA'

Finish with Tag C, by pasting in the Javascript code for your third tag, end it with

dataLayer.push({'event':'doneWithTagC'});

and set its firing rule to

{{event}} equals 'doneWithTagB'

What we’ve done here is most clear with a simple diagram:

Start Tag A -> Fires on dom ready (gtm.dom)
 -> sends event "doneWithTagA" to the dataLayer
Tag B fires on "doneWithTagA"
 -> sends event "doneWithTagB" to the dataLayer
Tag C fires on "doneWithTagB"
 -> sends event "doneWithTagC" to the dataLayer

Aha! It should be fairly clear now, that this creates a chain of events that fires our tags in the exact order we specify, starting when the moment the DOM is loaded.

We’ve tested this quite thoroughly on a live production site that gets millions of pageviews per month, and it seems to work out exactly at we’ve written here.

During testing and while using Google Tag Manager’s Preview & Debug feature, we added a simple

console.log('doneWithTagX');

to each of our tags, and not once did we see our tags loading in any order but the chained-event firing order we set up as described above. One note is that the scripts that load and fire are reported in reverse order in the Preview and Debug feature of GTM. The console.log() messages helped us to verify that these tags were indeed firing in the order we specified.

If you use this technique, we’d love to hear about it! Please, always use a test profile before making changes to your analytics tracking. We hope this post provides you with some new insight into how Google Tag Manager can be leveraged to deploy more of your Javascript code across your web properties.

Keep an eye out for upcoming posts on our experiences with other TMS platforms and  happy tagging…

  • https://plus.google.com/u/0/105204161368183855505/ Caluori

    Brilliantly logical solution for tag load order. Thank You!

  • http://jeffwidman.com/ Jeff widman

    What would be the use case for wanting tags to fire all of these tags, but in a specific order?

    It makes sense that sometimes you’d want to fire one or the other, but I don’t get why you care about order if they’re all firing anyway.

    • iampatgrady

      In my case the first tags define objects that tags further down the line need.

      I kept getting “Object Object does not contain method XXXXXX”. This is because the objects from tag A hadn’t completed before tag B had fired.

  • Toye

    @jeffwidman:disqus an instance would be an event firing after the page view has been sent, particularly important if you are still using the “ga.js”

  • https://3dformation.com/ Offshore Services.

    Thanks for the shared this informative and helpful post. you have done awesome work. Thanks again.

  • Mickael Robin

    Thanks for this very interesting post.

    I noticed that gtm.dom is not well managed in Internet Explorer so I had to replace gtm.dom with gtm.load in my rules (waiting for my devs to add ‘event': ‘pushafterloadisfinished’ so I don’t have to wait for complete page load to trigger my rules…)

    => don’t you have issues on IE with gtm.dom? what do you think of gtm.load ?

  • http://www.baronen.org/ Andreas Eriksson

    Very nice and well explained post, saved me!

  • Pete

    Thanks for posting, addressed the exact problem I’m dealing with today.

  • ts

    I think the article has been updated. It seems like you can now control the firing order.

    “Yes, you can control tag firing prioritization in the Advanced Settings of a tag.”

    However, I don’t get how this new advanced setting helps, if they are also saying that “Tags will still be fired asynchronously (tags will fire whether or not the previous tag has finished.)”. Would you be able to help me understand this :)?

Copyright © 2014, All Rights Reserved. Privacy and Copyright Policies.