How to track Single Page Applications with GA4 and GTM?

Written by:  Photo de profil de Lucas Rollin Lucas Rollin

Updated: Saturday, October 7, 2023

What is a Single Page Application (SPA)?

A Single Page Application is a type of web page that loads all the code required for navigation from the very first page load. As the name suggests, it’s an application that loads a single page. This type of application is very beneficial for the user experience, because once the first page is loaded, navigation is very fluid. It may look like the URL changes, but in fact you always stay on the same page.

SPAs are often created using the following JavaScript frameworks Angular, React and Vue.js.

However, this type of application is not suitable for SEO (Search Engine Optimization), because search engines have difficulties understanding the organization of the website, given that there is only one page.

Google Analytics 4 offers a default feature for tracking SPAs, but this may not work in your case. That’s why we’re going to look at 3 different methods in this article.

What is the History API in JavaScript?

Without going into the technical details, the idea here is to provide a clear understanding of how SPAs work.

The history object is a JavaScript global variable used by most SPAs to manipulate browsing history.

JavaScript global variable history
JavaScript global variable history

If you’re working on an older SPA, it may not be using the JavaScript History API, in this case you’ll need to install Google Analytics 4 via method 3.

3 methods to track SPAs

Before detailing the 3 methods, it’s important to understand what’s happening on a SPA. To do this, we’re going to use an instance of Angular in which I’ve installed the Google Tag Manager tracking code.

Here’s what my Angular application looks like. You can test the application here.

The Angular application I use as an example
The Angular application I use as an example

I create a History Change trigger in Google Tag Manager to be able to view history change events in the data layer (this activates the history change listener).

History Change trigger
History Change trigger

Then, as soon as I navigate in the SPA, I receive History events (gtm.historyChange) in the Google Tag Manager preview mode.

As mentioned above, GTM listens for calls to the JavaScript History API, which is why we get these gtm.historyChange events.

History event in GTM's preview mode
History event in GTM's preview mode
History Change data layer event
History Change trigger

Method 1: Keep GA4 with default settings

Now let’s see what happens if I set the Google Tag for a new GA4 property on all pages.

Now, I receive History events (gtm.historyChange-v2) and History Change events (page_view).

The gtm.historyChange-v2 event is triggered as many times as the gtm.historyChange event because they listen to the same events (those from the History API).

However, gtm.historyChange-v2 is managed by GA4, whereas gtm.historyChange is managed by GTM.

This is why gtm.historyChange-v2 triggers a page_view event (named History Change in GTM).

This page_view event tracks all pages viewed using the history API.

This feature is enabled by default in GA4 enhanced measurement, and can be disabled when necessary. If you wish to transmit more information in the page_view event, you will need to use methods 2 or 3.

Default page_view event handling on a GA4 property
Default page_view event handling on a GA4 property

Method 2: Track page views with History Change trigger in GTM

To use this method, I disable page_view tracking when changing the browsing history in GA4 enhanced measurement settings.

Disabling page_view event from history changes
Disabling page_view event from history changes

Now, I only get the gtm.historyChange event, as the gtm.historyChange-v2 event is no longer in the Data Layer.

I’m going to create a GA4 page_view event in GTM that will be triggered on history changes.

page_view event configuration from History Change trigger
page_view event configuration from History Change trigger

Then, you can change the page_location and page_referrer parameters to use the variables in the Data Layer. This will allow you to study the real user paths within your SPA.

Method 3: Track page views via Data Layer

Method 3 consists in asking a developer to send a page_view event in the Data Layer when the user changes the view in the SPA.

Your developer probably doesn’t know anything about how Google Tag Manager and Google Analytics 4 work, so you will need to create a detailed data layer documentation explaning what you need to be implemented on the SPA.

dataLayer.push(
    {
        event: "page_view",
        virtual_page_title: "Tour of Heroes - Dashboard",
        virtual_page_location: "/dashboard",
        virtual_page_referrer: "/heroes"
    }
);
page_view event configuration from the data layer
page_view event configuration from the data layer