This is the fifth in a series of blog posts on Google Tag Manager. Read:

Part 1. What is a Container Tag?

Part 2. Google Tag Manager Series: An Overview

Part 3. How to organise a Google Tag Manager Implementation

Part 4: Tips and tricks when setting up a Google Analytics implementation in Google Tag Manager

At iProspect, we have been using multiple vendors for container tags since 2010. This series focuses specifically on Google’s new Tag Manager, providing an overview of the tool, helpful tips, hints, and learnings.

Since its release last year, Google Tag Manager (GTM) has seen widespread adoption across the online marketing landscape. Featuring integration with Adwords, DoubleClick and Google Analytics, high flexibility with Data Layers and no upfront cost, GTM is a logical choice for anyone looking to consolidate their Google tags.

GTM is not without its faults however. When compared with premium solutions, GTM is still in relative infancy, suffering the occasional technical hiccup and lacking active support. The data layer, while versatile, requires development time to implement across each page. When employing a GTM across an array of sites these hours quickly add up, detracting from the time-saving benefits of a container tag solution.

In a recent project we installed GTM on over 150 sites for a client. The scope for error and amount of work involved in tagging up each page with a multiple data layer elements was immense, so we decided to take some short cuts, creating a total of 14 container tags (each holding at least 10 sites) and employing custom tracking as a workaround solution. Here is a selection of the tricks we have learnt with GTM and Custom Tags.

Object-Oriented Tag Management

One of the more powerful options available via a custom tag setup is the creation of JavaScript tracking objects. Object-oriented programming itself is outside the scope of this blog, but the basic concepts can be applied to tag creation in a simple and highly labour-saving manner.

var _gtm = new Object();

_gtm.trackMe = function(){ my tag code }

google tag manager objectAs shown above, only a couple of lines of code are needed to set up a tracking object with a custom tracking function. This object can acts as a storage container for all of your tracking-related functions and variables. Once set, these can be accessed from other tags, enabling the creation of a dynamic and reusable tagging framework that avoids redundant code.

A great example of this in action is virtual pageview tracking with Google Analytics. I prefer to prepend all virtual page URLs with ‘/vpv/’ and strip out the file type (.php/.aspx etc.) to help distinguish them from regular pages. However, the code to do so can become quite verbose:

_gtm.trackVPV = function(vpv){

var page = (document.location.pathname.replace(/\.(.*)$/,”) + (document.location.pathname.slice(-1) == ‘/’ ? ‘vpv/’ : ‘/vpv/’) + vpv.replace(/ /g, ‘-‘)).toLowerCase();

_gaq.push([‘_trackPageview’, page]); // Classic Analytics

ga(‘send’, ‘pageview’, page); // Universal Analytics


With the creation of the pageview tracking function, tracking virtual pageviews becomes much simpler. Once the pageview tracking function has been set, pages can be tracked from other tags with only a single line of code.

_gtm.trackVPV(‘page name’);

Setting the domain for Google Analytics

Google tag manager tagsThis works well with a multiple sites per container setup. The basic idea here is to set the domain of each tag via a macro before Google Analytics (GA) has been called. Unfortunately, the default GTM macro set does not include an option to extract the root domain component of a URL that includes a subdomain. Our solution was to use JavaScript to strip out the domain from the hostname, assign this to a variable and create a macro within GTM that takes the value of the variable.

_gtm.hostname = function(){

var hostname = document.location.hostname;

var domain;

var n = hostname.match(/\.com?\./) !== null ? 3 : 2;

hostname = hostname.split(‘. ‘);

return hostname.slice(hostname.length-n).join(‘. ‘);


The problem with this is that the integrated GA tags will be called before the domain variable has been set. There are numerous ways to overcome this with rules, e.g. waiting until the Domain macro matches a regular expression, or utilising the built-in ‘gtm.load’ event. We decided to use this custom tag as a staging area for our GA initialisation, calling a final line of code:

dataLayer.push({‘event’: ‘GA_Ready’});

All GA tag rules must now satisfy the condition ‘{{event}} equals GA_Ready’. This ensures that GA only fires once the _gtm tracking object has been set up with functions relevant to GA.

Overriding Functions to Track Page Views

For websites displaying dynamic content (or a large amount of content) on a single URL, tracking content can be problematic at the best of times. With no obvious event-driven method of content generation it can be a nightmare. One site within our GTM implementation project utilised an extended page-scroll feature, with the content for the next page loaded as the user scrolled outside of the bounds of the previous page – all within the same URL. Obviously GA virtual page view tracking was necessary, the question was how best to implement it.

As it turned out, each content load was accompanied by a call to jQuery’s addClass() function. The class of the respective navigation element was changed to active. Overriding the base addClass() function to include a new trigger allowed for a virtual page view to be called every time the content changed, irrespective of the original event that triggered the change.

The code:


var original = jQuery.fn.addClass;

jQuery.fn.addClass = function(){

var result = original.apply(this, arguments);


return result;}


$(‘#id’).bind(‘trackPageView’, function(){

var page = $(this).text().replace(/ /g,’-‘);



Considering the breadth and scope for various combinations of function, tracking type, element and attribute, the applications of this from a tracking perspective are virtually limitless. Play around, explore and see if you can expand upon this basic idea.

Changing the Firing Sequence of Events

google tag manager firingOur custom tagging approach relies heavily on jQuery for binding events to page elements. This can present problems if the desired action already calls an event. Events in jQuery are automatically added to a queue; hence the tracking event may occur after an event that redirects to another page, resulting in the tracking event being lost. To solve this, we use a function that binds events to the beginning of the event queue.

$.fn.bindFirst = function(name, fn) {

this.on(name, fn);

this.each(function() {

var handlers = $._data(this, ‘events’)[name.split(‘.’)[0]];

var handler = handlers.pop();

handlers.splice(0, 0, handler);



This function adds an event to the queue in the same way as the regular bind function, then removes the event from the end of the queue and pushes it to the front instead. With this defined in our master staging tag, it can be called from any other tag:

$(‘element’).bindFirst(‘click’, function() { my tag code });

This will ensure that your code has a chance to fire before other events in the object’s queue.


In much the same way as no two sites are identical, no two tagging implementations are identical. A solution that appears a panacea for one site may break another site. Hopefully some of the concepts raised in this blog will give you a foundation on which to expand. Play around with the code and see how these ideas can be utilised and improved upon. Finally, always remember to preview your code before publishing!

Rachel Sweeney

Rachel Sweeney


Rachel Sweeney is Digital Specialist, Web Analytics & Conversion Optimisation at iProspect.