If you read my previous post on fetching the Client ID from the Universal Analytics tracker object with Google Tag Manager, you might have agreed with me that it sucks you can’t access the tracker object interface in real time using Google Tag Manager. This is because all of the set commands you add to a Universal Analytics tag template take place before the analytics.js is loaded and the tracker object is properly created.

The other issue with the tag template is that there’s no set way to access the tracker object anyway. I mean, you can use the set command, sure, but you can’t really use get or, for that matter, make use of any other interface methods you’d want to such as plugins (more on them in this post).

So, in this post I want to show a method you can use to actually mine the tracker object for whatever information you want, and at the same time ensure that the data is usable by the time your all-important Page View Tag fires. This is a notable improvement to the method I talked about in the previous post, which was to basically use a Window Loaded Trigger to fire a non-interactive Event Tag with the Client ID.

This article was inspired and intellectually fuelled by the amazing Carmen Mardiros (follow her: @carmenmardiros).


The Simmer Newsletter

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

The method

You’ll have to use Custom HTML for this. I know, I know! It’s a huge step backwards from the awesome, templated world you’re used to. Using a Custom HTML Tag is necessary precisely for the reasons I listed in the beginning. Until the Tag Template supports adding arbitrary JavaScript code between the create and send commands in the template, you’ll have to use a workaround.

The upside is that all you need the Custom HTML code for is to setup the tracker object, and then push an initialization event in to dataLayer, which will subsequently fire your actual Page View Tag. So, you’ll end up with one extra Tag and a very slight delay to your Page View Tag, but the delay is so minimal it doesn’t really make a difference.

Here’s what will take place:

  1. Tracker object for your UA-code is created

  2. The Client ID is extracted from the tracker object as soon as it’s available

  3. When the Client ID has been extracted, it’s pushed into dataLayer together with the initialization event

  4. This event fires your Page View Tag, and you can use a normal Data Layer Variable to retrieve the Client ID

The Custom HTML Tag

So, start by creating a new Custom HTML Tag, and make sure it fires on the earliest possible Trigger - usually the All Pages Trigger.

As for the code within, you’ll get that from your Google Analytics Admin, under Property Settings -> Tracking Info -> Tracking Code.

Copy-paste that into your Custom HTML Tag. Now, proceed to remove the line which says ga('send', 'pageview');. We’re removing this because we still want to use the actual tag template for sending the pageview hit.

Now, if there are any modifications you need to do, such as adding additional trackers, you can set them up here. This guide has been written with a fairly basic setup in mind.

NOTE! Any modifications to the tracker, such as allowLinker : true, custom cookie settings, and so forth need to be setup on this Custom HTML tracker, so that the Client ID you will be fetching from this custom tracker matches the one used by your main Page View Tag.

The next part is important. The analytics.js library is loaded asynchronously, which means that you don’t actually know when the tracker object has been created and its get method can be invoked. So, the library lets you pass a callback function to the ga object, which will be executed once the library has loaded and the tracker has been created. As I mention in the beginning: this feature is not available in the default tag template, which is why we need this workaround.

To add the callback, you add the following rows of code after the ga('create', ...); expression:

ga(function(tracker) {
  ...any methods which need the tracker object

Any code within the callback function will be executed only once the library has been loaded, the tracker has been created, and the tracker object responds to interface methods. In this callback function, we’ll first fetch the Client ID, and then push it into dataLayer together with an initialization event:

ga(function(tracker) {
    'event' : 'trackerReady',
    'cid' : tracker.get('clientId')

As you can see, I’m invoking the get command of the tracker object, and asking to retrieve the Client ID from the tracker. This wouldn’t be possible without the ga(function(tracker) {}) call.

My personal, finished example for the Custom HTML Tag looks like this. Remember, any customizations you need for the tracker object need to go here as well, so be sure to read up on how to set up advanced configurations for your Universal Analytics tracking code.

  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),

  ga('create', '{{GA Tracking Code}}', 'auto', {'allowLinker' : 'true'});  
  ga('require', 'simoPlugin'); // Any plugins you want to load would go here  
  ga(function(tracker) {
          'event' : 'trackerReady',
          'cid' : tracker.get('clientId')

Just a few comments on the customizations:

  • {{GA Tracking Code}} is a Lookup Table Variable which returns the property ID depending on a few conditions.

  • ga('require', 'simoPlugin'); is where you would load any plugins you want to use with your Tags. This is missing from the tag templates, and I really hope we’ll get the chance to load plugins soon.

That’s it for the Custom HTML Tag. The rest is very simple stuff.

Data Layer Variable and Custom Event Trigger

The two other things you’ll need are a Data Layer Variable for the Client ID, and a Custom Event Trigger for the trackerReady event.

Nothing complicated about this. The Trigger is really simple as well:

Once you have these two setup, all you need to do is modify your existing Page View Tag to accommodate these changes.

My Tag, for example, now has the Client ID as a Custom Dimension, and it’s set to fire with the Event - trackerReady Trigger we just created.


This is one of those articles that I hope becomes obsolete soon. The current Universal Analytics tag templates do not let you run arbitrary JavaScript (e.g. load plugins) or access the tracker object after it has been created, but before the ‘pageview’ hit is sent.

That’s why you need this workaround. On the other hand, this isn’t exactly a very complex thing to do, as you’re only creating one additional Tag to set up the tracker and channel all the subsequent tags to not fire until the tracker object callback function has been executed.

Time will tell when the Universal Analytics tag template supports these features. Personally, I hope soon. Google Tag Manager is already the de facto implementation mechanism for Universal Analytics, but if it doesn’t support advanced configuration of the tracker object, larger organizations especially might be deterred from migrating until such features are supported out-of-the-box.