hello@newnorth.nl+31 (0) 85 401 31 62
/Journal

Implementing GA4 on a Single Page Application

GuideAnalytics2024.09.22
Freek Kampen
Freek KampenCo-founder, New North Digital

A SPA doesn't load new pages, and GA4 doesn't expect that. What breaks, and how to fix it with the History Change trigger.

What makes a SPA different

A Single Page Application loads one HTML page and then updates it dynamically as the visitor moves around. Frameworks like React, Angular and Vue.js made the approach mainstream: less waiting, and an experience closer to an app.

You can spot one by three things. The URL changes without a visible page refresh. The source holds more script references than visible content. And the network tab shows few full page loads but plenty of AJAX or API calls.

Where GA4 falls over

By default GA4 assumes a new page also means a new pageview. On a SPA that assumption doesn't hold, and it produces four problems:

The four problems

  • Duplicate pageviews: a single visitor action gets counted as several views.
  • Skewed session duration: without page refreshes GA4 misreads how long a session lasted.
  • Missed interactions: important actions go unmeasured if GA4 isn't set up for virtual navigation.
  • Confused referrals: traffic sources aren't attributed correctly, so your referral data is wrong.

The fix: the History Change trigger

Google Tag Manager has a trigger built for exactly this behaviour. The setup, briefly:

How to set it up

  • Create a new GA4 tag in GTM.
  • Choose the History Change trigger. It picks up URL changes without a full page refresh.
  • Rename the event to something clear, for example virtual_pageview.
  • Pull the relevant information through GTM variables such as New History Fragment.
  • Test in preview mode before going live, and check the tag genuinely fires on every URL change.

What else helps

Push meaningful user actions to the data layer so GTM can pick them up. And create custom events in GA4 for virtual navigation and any other action that matters.

For attribution: hold on to the original referral data across multiple virtual navigations, or you lose the source. If your SPA spans several domains, turn on cross-domain tracking.

Want to talk about this?

Let's talk data.

Tell us about your stack, your goals, the data you wish you had.

Takes 1 minute