Skip to content

Tracking fragments based navigation websites with GTM the right way

David Vallejo

We’re going to learn how to track those websites where the navigation is based on Ajax, ie: no pages reloads with Google Tag Manager.  As you may know a full page reload is needed in order to have Google Analytics tracking your pageviews, but those sites like the ones based on AngularJS are not reloading the page just the current page content, so this new pages won’t be tracked by our Analytics tools, or even catched by our conversion pixels.

Those sites use the popstate event, to push a live URI change in our browser without reloading the page. We could write our own “popstate listener” to catch up those changes, but GTM is pretty smart and it has a tool called history listener , that we’ll use to track those uri changes.

Every time that GTM detects a popstate event it will push an automatic event to the dataLayer called “gtm.historyChange” along with the previous fragment value and the new pushed one :


So basically what we’re going to do is adding a new pageview tag that is gonna be fired when this event is pushed to the dataLayer, but there’re some points that we need to have in mind:

  1. What happens if an user lands directly into a page with a hashtag, Google Analytics will just grab the current location.pathname +
  2. Since Universal Analytics was launched, the referral behaviour changed, now it will overwrite the current visit attribution when a new referral is found while this domain names has not been added to referral exclusion list within our properties configuration section.

Luckily we can think in some extra configurations in our Google Tag Manager container configuration to fix those previously mentioned situations.



  • 3 tags ( 1 will be fired when page is fully loaded, the second one will be fired based on the “gtm.historyChange” event and the last one will be the history listener tag type )
  • 2 firing rules ( First rule will allow us to fire a pageview web the user lands in our website the other will allow us to fire a virtual pageview when the uri changes without a page load )
  • 4 macros ( Here’s were we’re going to deal with the 2 problems we mentioned about before )


History Listener Tag

 Page Load Pageview Recording Tag

Fragment Change Pageview Recording Tag


Rule for the default pageView Tag

Rule for the fragment change pageView Tag


Macro for fixing the pagePath for page load Pageviews

Macro for fixing the pagePath for Fragment Pageviews

Null Value Returning Macro

There we go, now our Google Tag Manager container will record the right pageviews taking in mind the fragment part when registering the pagePath, and it will take care of firing a new virtual pageView when the pages fragment is uptated. Just off the record, this will work too for implementation not only changing the fragment but for all page types that change the uri path in the fly. ( ie: /contact.php to /aboutus.php without a page reload )

Any thoughs about this post ?, any improvement that you’ll have done to have a better tracking ?, Just leave a comment so we can discuss about it 🙂