Tracking Single Page Applications in Google Analytics 4 Properties

April 06, 2021
Analytics Consultant

With the announcement of Google Analytics 4 (GA4) Properties being the way of the future, many organizations are taking a serious look at implementing GA4 alongside their existing Universal Analytics properties. And if you're not...you should be!

Unfamiliar with GA4? We have you covered—check out some of our resources on the newest version of Google Analytics:

Google Analytics 4 Properties: Everything You Need to Know
Unified Data With Google Analytics 4 Properties
Get the Most Out of Your Reporting with Google Analytics 4 Properties
Explore Depths of Your Data in Google Analytics 4 Properties' Analysis Tools
Linking Google Analytics 4 Properties to Google Ads: How-to Guide

 

Before we start, though, if you haven't created your GA4 property and data stream(s) yet—go check out Emily Rosche's great guide to implementing Google Analytics 4 Properties on Your Website & Mobile App.

Single Page Applications

Single Page Applications (SPAs) are websites where each page of content doesn't require a new page load. Tracking Single Page Applications have always had their own nuances to account for with Universal Analytics—we wrote about that here. However, GA4 Properties offer a new and ever-evolving feature set we need to consider.

When working with SPAs and GA4, there are three areas where we will need to modify the way that we collect data: inside the Google Analytics interface, on your website itself, and in Google Tag Manager (or your tagging platform of choice).

Inside Google Analytics

Disable Automatic Event Tracking in GA4

When configuring a Web Data Stream in GA4, there is an option for "Enhanced measurement." This is meant to be a plug-and-play pageview/event tracking feature that only requires the flip of a toggle to configure. Typically, these events do not require any additional configuration.

However, because of the nature of some Single Page Applications, the Enhanced measurement feature might not operate as expected—potentially overstating or underrepresenting the intended events (eg. scroll events or search results).

To ensure accurate reporting, we recommend disabling this feature at this time. If you have opted to enable automatic pageview (and other events) tracking in your GA4 property, you are going to want to disable that feature prior to pushing your changes live to avoid potentially double-counting pageviews or accidentally overriding what is going to be sent from the data layer. 

Visit the Admin > Property > Data Streams section to turn off the Enhanced measurement feature:

Toggle the Enhanced measurement feature 'off' in the GA4 interface

On Your Website

Declare the Page Title & Page Location (Path)

To fix any data collection and accuracy issues involving pageview counts and errors associated with tracking Single Page Applications, we'll want to manually set the page_location and page_title sent to GA4 each time new content is loaded on your SPA.

By default, Google Analytics will use the value of document.location.pathname and it will be stored as the Page dimension in Google Analytics. You can override this with a path of your own. The value you set to the Page dimension must start with a forward slash (/) and should be formatted in the same manner as a page path.

You can also change the value for the Page Title dimension. By default, the page title in Google Analytics will be displayed as the variable inside the <title> tag on the page at the time the hit is sent. If your application already changes the <title> tag when the state changes, you're all set.

If that's not the case, see below for examples on how to override that value using the Data Layer and Google Tag Manager.

Example One With Data Layer Variables

<script>
var dataLayer = window.dataLayer = window.dataLayer || [];
dataLayer.push({
  'event': 'pageview',     
    'page_location': {{dlv - page_location}},
    'page_title': {{dlv - page_title}}   
    
});
</script>

Example Two with Expected Values

<script>
var dataLayer = window.dataLayer = window.dataLayer || [];
dataLayer.push({
  'event': 'pageview',     
    'page_location': '/',
    'page_title': 'Home'   
    
});
</script>
BONUS! Other Methods of Setting Location & Page and Addressing Rogue Referrals

Simo Ahava has an excellent implementation guide that provides additional methods of setting and storing the 'page_title' and 'page_location' in GTM using JavaScript and explains/addresses the 'rogue referral' issue encountered on Single Page Applications.

This guide would be especially useful if you don't have the development resources or ease of manipulating the data layer prior to GTM loading on your site. Simply use the combination Custom JavaScript and Data Layer Variables you create in his guide in place of the Data Layer Variables we use below!

Inside Google Tag Manager

Step One: Create GA4 Configuration Tag

In our GTM container, there are two new tag types available to us specifically for GA4; Event tags and Configuration tags. The Configuration tag acts like our traditional Universal Analytics Pageview tag because it sends the 'page_view' event. The configuration tag also determines which parameters will be sent with page_views as Custom Definitions, or which fields need to be manually set, such as 'page_location' and 'page_title'.

Select the GA4 configuration tag type in the GTM interface

 

Select the GA4 Configuration tag type and input your Measurement ID information as shown below:

GA4 Configuration Tag in GTM interface
Step Two: Create Data Layer Variables to Manually Set Page Name & Path

Data layer variables will need to be created for 'page_title' and 'page_location' to scan for these values during each 'pageview' event and to be pass in the Configuration tag's Fields to Set section.

Data Layer Variable setup in GTM interface
Step Three: Fields to Set in Configuration Tag

Visit the Fields to Set menu in your GA4 Configuration tag to manually set the page_location and page_title using the Data Layer Variables we created above.

Fields to Set menu in the GA Configuration Tag Settings

 

Note that we have the Field Name 'debug_mode' set to 'true'. This should only be enabled during the QA/debugging phase for new assets or those being modified. We do not want 'debug_mode' to be enabled for all production tags and end-users to show up in GA.

Step Four: Add Custom Event Trigger

You will need to create a new Custom Event trigger set to fire on all 'pageview' events that are now being sent in the data layer. We'd expect this event to fire when new content loads and the URL doesn't change or using them as virtual pageviews to create a funnel in a commerce checkout or application process—i.e., anytime you would want to track something as a pageview.

Custom Event trigger setup for ‘pageview’ in GTM interface

 

Add the trigger to your GA4 Configuration Tag and try it out on your site.

Successful tag firing on the ‘pageview’ event in GTM debugger interface

Using Debug Mode in GA4

Ensure that the manually overwritten 'page_title' and 'page_location' fields are being set properly in real-time using GA4's enhanced Debug Mode. The debug view report within the interface (located at the bottom of the navigation panel) will show all of the data associated with the user's visit to the site—including all parameters used as dimensions and metrics!

To properly use the debug reporting in GA4, ensure that you select your own debug device from the dropdown menu which is located in the top left of the screen. This will ensure that you are viewing your hits, and not a fellow team member's session!

Example of Debug Mode in GA4 interface

Overcoming the Hurdles for Migrating Single Page Applications

Collecting consistent Page Title, Path, and referral information are just a few hurdles we've experienced when migrating a Single Page Application's existing Universal Analytics implementation to Google Analytics 4.

We showed how to solve them using a combination of Google Tag Manager and your site's data layer, but there are many potential ways to implement the solution we set up today.