By Chris Berger

Just as you thought Christmas was over, Google surprise everyone with two extra gifts – JavaScript Error and History Listeners in GTM! In this post I’m going to delve into the inner workings of these listeners and some examples / uses for the both of them

Back to blog home

The History Listener

Anyone who’s implemented basic Google Analytics tracking on a site will know that a pageview is fired off when the GA code snippet is loaded.

The issue with this is that where content is loaded/shown dynamically on a web page (without the page reloading), a pageview is not fired.

In GTM this would traditionally be tracked by adding an entry into the data layer whenever in-page content changes. For example, new content loaded via AJAX would contain a JS push to the data layer which shows that the new content was loaded. Obviously this is less than ideal as it requires code changes / developer resource, which could take a considerable amount of time.
The new History Listener overcomes this by allowing you to track when a user’s current browser history entry changes.

AJAX & URL Fragments

Before getting to grips with exactly how this feature works it’s advisable to at the very least have a loose understanding of AJAX and URL fragments.

Totally coincidentally, there is a loose explanation of both below! (You’re welcome).
Of course if you’re already clued up on these, move on to the next section.

AJAX (Asynchronous Java And Xml) allows a web page to dynamically load new data/content without actually reloading the page. The example below is of a live weather widget on a web page constantly receiving updates on the current weather and displaying this to the visitor:

Obviously it wouldn’t make sense to constantly reload the entire page every time the weather changed (especially in the UK!). Instead, an AJAX request is made that receives the weather’s current state at set intervals and re-renders the weather widget only.

URL Fragments allow users to switch to a particular piece of content on a web page, again without the need to reload the page. This works by appending a fragment (hashtag and identifier, e.g. ‘#example’) to the end of the request URI using an anchor link or JavaScript for example where the identifier is the ID attribute of the element the user is being directed to.

Using an anchor link or JavaScript, a fragment (hashtag and identifier, e.g. ‘#example’) is appended to the request URI which directs the user to the element with an ID attribute matching the identifier.

For example, a common use of URL Fragments is a ‘back to top’ link on a page. The title of this blog post is rigged with an id attribute (‘blogTitle’) and the below Back to top link has an href attribute ‘#blogTitle’. Try this out and note how the fragment is added to the URL in your address bar:


The similarity between AJAX and Fragments is that they should both create a browser history entry when they are triggered (in most popular browsers URL Fragments create them automatically, however with AJAX these must be added manually e.g. with JavaScript).

The following functions of the window.history object allow manipulation of a browser’s history:

window . history . pushState() – Add a new history entry
window . history . replaceState() – Modify the current history entry
window . history . popstate() – Called when the current browser history entry changes

The GTM History Listener will be triggered when the above three functions are called. popstate() is automatically called when the URL fragment changes.

Here are examples of what is pushed into the Data Layer after each of these functions are called:

Push State:

Replace State:

Pop State (called by altering the URL fragment):

Notice how all of these historyChange Data Layer events contain the same attributes making it easy to implement a GTM rule to cover all trigger sources.

Setting Up the History Listener in GTM

To add the history listener to your site, create a new tag and change the tag type to Event Listener > History Listener:

Next create a rule or apply an existing rule to specify the pages of your site where you want the listener to be used. This example will include the History Listener on all pages of a site:

That’s it! Your listener is now ready to fire.

Handling History Changes

Assuming you’ve now set up the listener in your chosen GTM container, you can now configure the container to act on a history change.

Using the Back to top URL Fragment as an example (shown earlier in this blog) I’m going to show you how to track history state changes by firing an event every time the Back to top link is clicked.

1) Create a new Google Analytics tag with an appropriate tag name and UA number, then change the Track Type to Event. Next add a sensible Category and Action (with optional Label/value) for the event to identify this in your GA reports:

2) Next create a version 2 dataLayer variable that will hold the value of the new URL fragment for history changes:

NOTE: You may already have the history data layer variables set up as macros by default if you created your GTM container after the history listener was made available. This would appear under macro name history new url fragment.

3) Lastly, create a rule that orders the event tag to fire when a history change is detected and the New URL Fragment macro is ‘blogTitle’:

Once this is all saved, you are ready to test and publish the changes in GTM’s preview and debug mode. If everything looks good and the event fires as and when it should, create a new container version and publish the changes to start accumulating data for your history events in GA.

The JavaScript Error Listener

Now on to the GTM JavaScript Error Listener. Surprisingly enough, this listens out for uncaught JavaScript errors that occur on your site.

The majority of JavaScript errors occur behind the scenes and don’t usually have a noticeable negative impact on a site’s performance or functionality. However, a real stinker can sometimes pop up leaving a lasting poor impression of your business and maybe even preventing some users from converting (even if that was their intention!).

This could be the result of inadequate testing or even an uncontrollable change such as a browser update which is less robust when it encounters particular errors in your script.
Either way it is highly recommended that the JS Error listener be configured in all of your GTM containers.

The only downside of the JavaScript error listener is that it will only be begin listening for errors after the GTM container is loaded (on the gtm.js event) and the page DOM is ready (gtm.dom event).

Setting Up the JavaScript Error Listener

This is configured in almost exactly the same way as the History Listener (or any other GTM listener for that matter).

1) Start by creating a new tag, this time selecting Event Listener > JavaScript Error Listener as the tag type:

2) Again create a rule or apply an existing rule to specify the pages of your site where you want the listener to be used. The following will include the JavaScript Error Listener on all pages of a site:

Handling JavaScript Error Events

As with the History Listener example, we are going to configure our GTM container to fire off a GA event when the listener is triggered.

Our event will have the following category, action and label set:

Category: “JavaScript Error”
Action: URL of the script where the error occurred with error line number prepended
Label: Error message returned

So for example:

Category: “JavaScript Error”
Action: “line 3:”
Label: “Uncaught ReferenceError: foo is not defined”

1) This time we’ll start by creating the three version 2 dataLayer macros to hold the information about our JavaScript errors (error url, error message and error line number):

Error URL:

Error Message:

Error Line Number:

2) Next create the Google Analytics event tag utilising our macros in the action and label fields:

3) Finally, apply a rule to your event tag that orders it to fire when a JavaScript error is detected (when event equals gtm.pageError):

Once this is all saved and you are happy with everything, create a new version containing your new tag and publish it in GTM.

What Next?

Once you have set up the error listener and enough data has accumulated (leave for about a week, or less for higher traffic volumes), segment your users and compare the behaviour of those who have encountered JS errors on your site with those who have not. If it seems to have had a negative effect on visitors (e.g. less pages viewed per visit or a lower conversion rate) investigate further and find the particular error(s) that are mainly responsible for this.

These will be your priority when it comes to solving errors on your site!

Share this article