Tracking page changes in an SPA with GA/GTM

This article describes a technique for capturing "page changes" in an SPA when trying to track user movement using Google Analytics (GA) and Google Tag Manager (GTM).

For background, an SPA, or single-page web application, uses a browser technology called the History API, or window.history. It allows the recording of the movement around a web application without actual page loads into a stack, allowing the back and forward buttons to do something meaningful even though real page loads are not occurring.

The History API exists consistently in all modern browsers, and it turns out that Google Tag Manager can actually observe changes to it and push tags around accordingly. This isn't default behavior, however; it has to be configured to do so.

Step 1#

The first thing that has to happen is deciding what parts of the URL to track as individual pages. By default GA doesn't track anything but the URL (leaving off the ?query=string and #hashtag information), however these components can be useful sometimes in an SPA in a way that they weren't previously in a traditional web application. For example, we could use #hashtags to show certain dialogs over the top of another page, in which case the /main/url part of the URL is the main page content we show, the #hashtag represents which dialog is currently displayed.

Then, within Tag Manager you can create a Custom Javascript user-defined variable that combines all of these things together in a single value. For one customer's implementation, here's the function I ended up using—

// this function will return the current page URL, plus ?search, plus #hash in one string
function() {
return window.location.pathname + window.location.search + window.location.hash
}

Variable Configuration

Step 2#

Add a History Change trigger that fires on all events. This is a built-in trigger that doesn't require configuration.

History Change Trigger

Step 3#

Keep your existing Google Analytics tag for regular page loads, but then create a new Google Analytics: Universal Analytics "tag" to for triggering Page Views when the History Change trigger fires. The configuration for this is:

  • Track Type— Page View
  • Google Analytics Settings— (not sure here, I just used the UDF that one of you had set up previously, which was present on the other tag that already existed
  • "Enable overriding settings"
  • Under "More Settings" / "Fields to Set", set the "page" Field Name to the {{user-defined variable}} set up in Step 1.

Finally, set up the tag to trigger off the History Change trigger set up in step 2. Put all together it looks like this—

Tag Configuration

This setup is pretty generic and should work for most SPA situations as long as they are firing the History Change event, which any modern webapp using this technique should do. I didn't have to mess with dataLayer or anything like that to get this to work, it just did as soon as I created this configuration within Tag Manager.