[GTM] Pitfalls and Countermeasures for SPA website measurement with GA4
ライター:JAIN Vibhor

デジタルマーケティングエンジニア 西村 彰悟のコラム「[GTM] GA4によるSPA計測の罠と対策」をデジタルマーケティングエンジニア JAIN Vibhor が英訳したものになります。

SPA measurement with GA4 can be complex, with several intricacies such as – incorrect custom dimensions values, duplicate page view measurements, and inability to measure despite perfect GTM setup – to name a few. In this article, we explain the reasons behind these issues and provide solutions to address these issues.

For those who are only interested in solution, you may jump to the chapter on Setting up virtual page view measurement to avoid pitfalls in SPA.

  1. What is SPA?
  2. GA4 automatic SPA measurement does not update custom dimension values
  3. GA4 automatic SPA measurement does not utilize page_location, page_title override settings
  4. Set up Virtual page view measurement avoiding the SPA trap
    1. Google Tag Manager settings
    2. GA4 Admin settings
  5. GA4 automatic scroll measurement does not support SPA
  6. Conclusion

※ GA4 is an evolving product, some content in this article article may change. Please use Chrome Developer Tools, GA4’s DebugView, and reporting for verification when configuring.

1. What is SPA?

SPA stands for Single-Page Application, which refers to dynamic websites or web apps mainly built using frameworks such as React, Angular, Vue.js, and others.

For a typical website, clicking a link triggers a full page reload, refreshing the entire content. However, in an SPA (Single-Page Application), JavaScript allows for partial updates of the page, enabling fast page transitions and achieving a rich UI/UX similar to native apps.

During this process, although the URL and page title are modified, giving the impression of new page navigation to site visitors, from a technical standpoint on the browser side, no actual page navigation has occurred (what GTM considers as equivalent to the “page view” trigger event).

In order to trigger tag settings for each page transition in an SPA environment, one of the following approaches is required:

  • Combine the “History Change” event trigger and page view-based triggers.

  • Implement the necessary adjustments on the website, notifing GTM (Google Tag Manager) via the custom events of the timing of page views transitions. This can serve as an alternative to page view triggers.

Here is an example code snippet for notifying GTM (Google Tag Manager) of page display and transition timing in an SPA using custom events:

window.dataLayer = window.dataLayer || [];
  'event': 'trackPageView',
  'pageUrl': 'https://example.com/article/why-you-should-have-a-cat-five-reasons?aa=bb',
  'pageTitle': 'Column 5 Reasons You Should Get a Cat'',
  'pageCategory': 'article',

In GA4, you don’t need to perform such complex configurations. The web stream’s enhanced measurement feature automatically detects history change events and sends the “page_view” event without requiring such manual setups. This feature is enabled by default. However, this functionality can become a pitfall for intermediate users who have just started utilizing GA4.

GA4 supports SPA page transitions by default through the enhanced measurement feature.

2. GA4 automatic SPA measurement does not update custom dimension values

When the “page_view” event is automatically sent during SPA page transitions, parameter values set in the GA4 Configuration tag are not updated to match the contextual values of the new page. Instead, the values form the very first firing of the GA4 configuration tag is retained and used throughout.

For the measurement using the enhanced measurement feature, the parameter value in the GA4 configuration tag are not updated with each SPA page transition.

Let look at the specific example. Suppose you have configured to send only the path portion of the page URL to a parameter named “path.” When an SPA screen transition occurs from “https://example.com/cat/” to “https://example.com/dog/”, the measurement would be as follows:

  • When “https://example.com/cat/” is opened, the “path” parameter value would be “/cat/”
  • However, in the event sent after transitioning to “https://example.com/dog/” in the SPA, the value would still be “/cat/”

During SPA page transitions, the automatically sent “page_view” event retains the previous value and is not updated to “/dog/”. This behavior is similar to when a “page_view” event tag without any parameters is fired. The GA4 configuration tag created within GTM will not be triggered again.

(The automatically triggered “page_view” tag actually utilizes the values of the “gtm.newUrl” and “gtm.oldUrl” dataLayer variables from the custom event “gtm.historyChange-v2” automatically triggered by the GA4 tag. These values are injected into “page_location” parameter (the currently viewed page’s URL) and “page_referrer” parameter (the referring page’s URL) fields.)

3. GA4 automatic SPA measurement does not utilize page_location, page_title override setting

If you have configured the GA4 configuration tag to send custom values for “page_location” and “page_title” parameters, the automatically triggered “page_view” event during SPA page transitions faces the same limitations as mentioned earlier. Specifically, the following behavior occurs.

If you are overriding the “page_location” (the viewed page URL information)

For each event, the following values are used as “page_location”:

  • Automatically measured “page_view” event in SPA: The URL after the page transition in SPA.
  • GA4 events occurring after SPA page transitions: The value previously set by the “GA4 Configuration Tag” as the “page_location.”

If you are overriding the “page_title” (the viewed page title information),

Both the automatically measured “page_view” event in SPA and the subsequent events use the value previously set by the “GA4 Configuration Tag”. This takes precedence over the new page title information after the page transition.

If you haven’t made any custom parameter settings or overwritten the page URL, you can ignore these issues. However, if you have implemented such configurations, additional settings will be necessary. In the next section, we will discuss specific solutions to address this issue.

4. Set up Virtual page view measurement avoiding the SPA trap

You can address SPA measurement issues implementing the following three settings:

  • Configure the GTM to trigger the GA4 configuration tag during each SPA page transition.
  • Disable the “Ignore duplicate instances of tags on this page” setting in the Google Tag section of the GA4 management interface.
  • Disable the measurement of SPA page transitions through the enhanced measurement feature in the GA4 management interface.

4.1. Google Tag Manager settings

In Google Tag Manager, configure the GA4 configuration tag to fire every time there is an SPA page transition. The easiest way to do this is to trigger the GA4 configuration tag  on each associate the “History Change” trigger.

(However, there are edge cases when depending on the structure of your website, this method may not work as expected. In such cases, you can consider modifying your site to push custom events to the dataLayer during SPA page transition timings.)

Creating variable settings

First, create two data layer variables that capture the previous URL and the new URL on history change event:

  • Data layer variable “dataLayer – gtm.oldUrl”;  Variable name: gtm.oldUrl
  • Data layer variable “dataLayer – gtm.newUrl”; Variable name: gtm.newUrl

Similarly, create “dataLayer – gtm.oldUrl” in the same way

History change events can occur multiple times during a single page transition. We only want to track page_view events for history change events that involve URL changes. To achieve this, we will create a custom JavaScript variable that makes use of these newly created data layer variables to detect URL changes.

  • Custom JavaScript variable “cjs – page url changed”
  • Custom JavaScript: Use the following code
  return {{dataLayer - gtm.newUrl}} !== {{dataLayer - gtm.oldUrl}}; 

Trigger Settings

Using the variable setting “cjs – page url changed”that we created earlier, we will now create trigger settings that respond to history change events only when the page URL changes.

  • Trigger Settings “History Change ※Only when URL changes”
    • Some History Changes
      • “cjs – page url changed” == true

If there are additional conditions required, such as restricted domain, you can add them to this trigger.

GA4 tag Settings

Make the following adjustments and save them in your current GA4 configuration tag:

  • Link the created “History Change ※Only when URL changes” trigger.
  • Set a new parameter named “page_referrer” and value set to the data layer variable “dataLayer – gtm.oldUrl” 

(Note1: If you need to handle SPA page transitions other than of the history change trigger, this method won’t generate the value for the page_referrer parameter.) 

(Note2: If you have separated the “page_view” event tracking tag and the “configuration tag,” use the tag sequencing feature to ensure that the “GA4 configuration tag” is loaded immediately before the “page_view” event tracking tag. Override values such as page_location, page_title, and page_referrer in the “configuration tag.”)

The GTM configuration is now complete. 

For this measurement to work correctly, additional two settings need to be changed in the GA4 Admin section. Before publishing the GTM configuration, please follow the steps below

4.2. GA4 Admin settings

After making the following two configuration changes, publish the GTM configuration we made in earlier sections.

Allow multiple executions of GA4 configuration tags on the same page.

By default, GA4 configurations tag fires only once per page and any additional calls  will be ignored, resulting in the tag firing without any effect. To remove this restriction, follow the steps below.

1. Open the GA4 Admin section.

2. Under the “Property” column, click the “Data Streams” menu, and then select the web stream you want to configure to open the “Web Stream Details”.

3. Under the “Google Tags” section, click “Configure tag settings” 

4. Click “Admin” tab at the top, and then under the “Google tag management” section, click “Manage Google tag

5. Under the “Additional Settings” section, toggle off the switch for “Ignore duplicate instances of on-page configuration” and click “Save”.

Disable SPA Measurement with Enhanced measurement

When both Enhanced measurement for SPA page views transitions and the corresponding GTM settings are enabled, it can result in duplicate firing from each setting. To prevent this, disable the Enhanced measurement t feature.”

1. Open the GA4 Admin section.

2. Under the “Property” column, click the “Data Streams” menu, and then select the web stream you want to configure to open the “Web Stream Details”.

3. Under the “Events” section, click gear icon next to the “Enhanced Measurement”

4. Click on “Show advanced Settings” for the “Page Views” section, uncheck the option “Page changes based on browser history events” to disable it and click “Save”.

After making the above changes, you can publish the GTM configuration you created earlier to enable measurement for your SPA.

When parameters cannot be retrieved correctly 

Depending on the structure of your SPA website, there may be cases where necessary parameter values, such as the page title, are still not updated upon the “History Change” trigger is fired. In such cases, you can push a “Custom Event” to the dataLayer at the appropriate timing when the required information is ready on the website. You can then use this custom event as a trigger for your GA4 configuration tag.

window.dataLayer = window.dataLayer || [];
  'event': 'trackPageView',
  'pageUrl': 'https://example.com/article/why-you-should-have-a-cat-five-reasons?aa=bb',
  'pageTitle': 'Column 5 Reasons You Should Get a Cat'',
  'pageCategory': 'article',

5. GA4 automatic scroll measurement does not support SPA

By default, GA4’s automatic scroll tracking does not resume tracking when navigating through SPA pages. However, there are solutions available. If you’re interested, you can refer to the author’s Qiita article titled “How to Track GA4 Scroll Events in SPA” for more information.

6. Conclusion

GA4 tag setup is more challenging than Universal Analytics tag setup, more so for SPA websites if you do not understand the specifications of how it works. When setting up, be sure to check the measurement results in the Chrome Developer Tools, GA4 DebugView, and reports.


JAIN Vibhor