Tips to track an ajax based website using GTM and Universal Analytics

I’ve been dealing with some Ajax based website tracking these past months (mostly AngularJS based ones), and I’ve learn a lot of stuff , mostly some important points about how Google Tag Manager does work.

Usually tracking an Ajax based website is a PITA, since mostly we don’t have page reloads as all the content is loaded asynchronously. So either you ask the developers to push you the content loaded info into the dataLayer or you play with the history location.

Still we need to have some points in mind while tracking those sites with Google Tag Manager (and maybe natively or using any other tag management system).

1. Use a fixed tracker name

The way Google Tag Manager works, everytime a Google Analytics tags is fired it creates a new tracker with a name (“GTM”+Current timeStamp ). This is not a problem for most tracking implementations, but we need to take in mind that websites based in Ajax usually changes the current URI without even needing to reload the page, so it may happen that if we’re using the campaign tagging we may ending having a lots of unneeded visit respawn and referrals.

Let me explain this with a simple example: has a link to our site and it’s using the campaign tagging to allow us to track their visits to us.

So the visit will end in our page with the following values:


Let’s map this to Universal Analytics parameters:


Universal Analytics uses the “dl” parameter  (document.location) and dr(document.referrer), to calculate the visit attribution. It will search for gclid, utm_ parameters in the “dl” parameter value (in that order of preference) and if it doesn’t find them it will try to calculate the attribution from the “dr” string.

As we have the the utm parameters in our landing page, the referrer won’t be taken in mind to calculate the visit attribution, so we’re ok at this point.

source: test_source
medium: test_medium
campaign: test_campaign

But if the visitor decides to go to another page, and like we said in this case there will be no page reload  Google Tag Manager will spawn a new tracker and we’ll end having those values.


As we said before if there’re no utm or gclid parameters in the document.location Google analytics in going to look to the document.referral string and it will find a different domain than the current loading one, so it will track a new visit:

medium: referral
campaign: /

D’oh. This is wrong, we’ll miss the original visit attribution, plus we’ll have some extra ghost sessions in our data.

Best way to do this (even if it’s not recommended) to set a fixed tracker name in our tags.


This way, the same tracker instance will be used everytime and the original dl parameter will be kept.

2. Force the Non-Interaction Flag to false in your pageviews

This is another important point to have in mind. Google Tag Manager uses the set command to set the values instead of setting them directly to hit. So if we fire and non-interactive event tag, the subsecuent hits will inherit that flag making the subsecuente pageviews to have the “ni” parameter attached to them.

Let’s how Google Tag Manager is going to translate a single Event tag:

ga("create", "UA-40180485-1", {"cookieDomain": "auto","name": "myTracker"});
ga("myTracker.set", "&gtm", "GTM-MW3DNR");
ga("myTracker.set", "nonInteraction", true);
ga("myTracker.send", {"eventAction": "test","eventCategory": "test", "eventLabel": "test","eventValue": undefined,"hitType": "event"});

As you can see the nonInteraction is globaly for the tracker, and this will affect our next pageviews (remember that we don’t have any page reload so the nonInteraction flag will be kept till we disable it.

An easy going fix for this without needing to deal with hitCallback/eventCallback is to automatically remove the “ni” parameter for all pageviews as it’s not likely going to need it (ever used a non-interactional pageview?).

Let’s see how can we achive this. We can’t use undefined string on GTM input boxes as it will be treated as a string, therefore we’re going to create a new Variable that is going to return us the real undefined value.

ow we can safely force the “ni” parameter to undefined in our pageview tags this way:


Did you fance any other problems when tracking ajax based sites?, share them in a comment 🙂

Greets: Thanks fly one more time to Yehoshua Coren from Analytics Ninja, for reviewing these points with me.

Author: David Vallejo

Google Analytics Consultant and implementer. I have some experience with Google Tag Manager Follow me: @thyng

9 thoughts on “Tips to track an ajax based website using GTM and Universal Analytics”

  1. I think i be missed something – why Google Tag Manager will spawn a new tracker when the visitor go to second page?
    If your page isn’t reloaded, then GTM will not run again so the pageview will not fired again, isnt it?

    1. Because that’s the way Google Analytics tags work in GTM. If you don’t define a tracker name for your tags (what is the recomended way to do it), everytime they are fired a new tracker initialization is performed with a semi-random tracker name ( “gtm”+{{current_microseconds}} ) .

  2. How many pageview trackers do we need to setup? Do we have just one with the field sets at the end of this article? Or, do we have a traditional tag and this tag?

  3. How is {{setDomainName}} set in this example? Is that simply a placeholder for the domain this code is being implemented on?

  4. Great article, thanks for these insights!

    I successfully implemented the solution for our client. I’ve a question about the why:

    “But if the visitor decides to go to another page, and like we said in this case there will be no page reload Google Tag Manager will spawn a new tracker and we’ll end having those values.”

    My question: Why and when does the GTM spawn a new tracker. Is this only the case for Ajax / Angular websites? Or is this alsways the case when you work with virtual pageviews?

    Thanks a lot!

Leave a Reply

Your email address will not be published. Required fields are marked *