Thursday, March 28, 2024
No menu items!
HomeData Analytics and VisualizationTrack Single Page Web App with Google Analytics 4 and Google Tag...

Track Single Page Web App with Google Analytics 4 and Google Tag Manager

Updated: May 17th, 2021. 

Important: this blog post contains Google Analytics 4 examples. If you are looking for Universal Analytics (GA3) examples, click here

*****

Tracking page views on regular websites is fairly easy: you just add a tracking code to every page and done! Every time a visitor clicks an internal link, a browser window refreshes, and a new page view hit is sent to Google Analytics.

But when it comes to single-page websites (or web applications), there are more nuances. Even though Google Analytics 4 now has a built-in tracking of such pageviews, it doesn’t always work out of the box. And some websites are just really inconvenient from the web tracking standpoint.

The result? Only the first page view is tracked. All the subsequent page views are not captured (until the visitor completely refreshes the page).

To mitigate this, you will need to do additional configuration to track such websites/web apps. But don’t worry, in this blog post, I will show you 3 methods of how to track single-page applications with Google Analytics 4 (and, in most cases, Google Tag Manager).

Why does this happen? Let me show you.

 

Table of Contents

+ Show table of contents + 

What is a Single Page App (SPA) / Website?
Install Google Tag Manager
Multiple ways of tracking SPA + How to read this guide
Do you need this guide at all?
Does the page URL change (when you navigate from page A to B)?
Method #1. Track pageviews with GA4 Enhanced Measurement
Method #2. Try the History Change trigger
How many History events do you see?
Sending data Google Analytics (thanks to the History Change trigger)
If URLs of your website contains #
If URLs of your website do not contain #
Trigger
Should the GA4 configuration tag automatically track the first page_view?
To sum up this chapter
Test the setup

Method #3: Track SPA with GTM and Developer’s help
Variables
Trigger
Create a GA4 event tag
Should you override parameters in the GA4 config tag?
Should the GA4 config tag auto-track the first page_view?
To sum up this chapter

Test the setup
Check the DebugView
There is no rogue referral issue in GA4
Conclusion

 

Video tutorial

If you prefer watching videos, here’s the tutorial from my Youtube channel. But if you want to get the most out of this topic, you should do both: watch the video and read the blog post.

 

What is a Single Page App (SPA) / Website?

Single Page Application (SPA) is a web application or website that loads all of the resources required to navigate throughout the site on the first page load. As the user clicks links/buttons and interacts with the page, subsequent content is loaded dynamically (and the page technically does not reload, even though it might look different).

The default Universal Analytics tracking works well with traditional websites because the snippet code is run every single time users load a new page.

However, in a single-page website/app, all of the necessary code is loaded once and the page does not reload during the entire user session. That is why you see only one page view in your GA3 reports. The URLs might change but that is just to give the perception of separate pages.

A lot of web tracking tools won’t work as expected with SPAs because they’re written for traditional websites where the tracking codes can detect when a new page loads.

When it comes to Google Analytics 4, Enhanced Measurement offers built-in pageview tracking in such situations. However, that does not work on all single-page websites, thus some additional GTM configuration might be needed.

Continue reading and I’ll show you how deep the rabbit hole goes.


Install Google Tag Manager

If you haven’t yet, install the Google Tag Manager to a single-page web app or website. I have published a blog post with several options for your consideration. Also, check whether your Google Tag Manager is working properly.

Done? Great, let’s proceed.

 

Multiple ways of tracking SPA + How to read this guide

There are three techniques explained in this guide:

Built-in tracking of Google Analytics 4 (this is the quickest one)
working with a History Change listener (within GTM)
asking a developer to push pageview data to the Data Layer every time a visitor navigates from one page to another.

But before we jump right into the configuration part, first we need to evaluate the context and find out which tracking option to choose. Just like in my other popular blog post about form tracking, to make complex things a bit more understandable, I’ve created a flow chart that can help you decide which tracking method to choose (or, in many cases, there will be only one method possible for you).

Note: If all 3 tracking options are possible for you, you should go with the developer’s help + dataLayer.push (as it’s proven to be the most robust).

First, let’s take a quick look at it, and then we’ll dive deeper into each step.

 

Do you need this guide at all?

The first diamond in the flow chart above asks a question: When you navigate between pages, do you see new pages in the GTM preview mode?

What does this question mean? By default, Google Analytics tag fires every time a page is loaded (meaning that the page must load completely from scratch).

Together with the page’s code, the Tag Manager JavaScript snippet is also loaded from scratch. So if you navigate from page A to B, you will see a new page title here. Every time this appears, it means that the page was completely (re)loaded.

So if on every pageview you notice that a page title on the left side of the sidebar, you are not working with a single-page application. Read my GTM guide for beginners, instead. I’ve explained there how to track your first GA pageview with Tag Manager.

On the other hand, if you’re really working with an SPA, every time you navigate from page A to page B, you won’t see the page title. Why?

That’s because in web tracking, “pageview” usually is when the page document is loaded and JavaScript tracking codes are loaded together with it (including Pageview tags). However, in SPA, all the subsequent “pageviews” happen dynamically, without loading/reloading the page document. That’s why by default, Tag Manager does not track “dynamic” pageviews.

Because of this, you need to do some additional configuration (and maybe even with the help of a developer).

Alright, so the first question is answered. If you are indeed working with an SPA, let’s move to the next question in our flow chart.


Does the page URL change (when you navigate from page A to B)?

If the URL does not change, you will have to ask the developer’s help. Immediately skip to chapter “Track SPA with GTM and developer’s help” of this blog post and continue reading from there. If the URL indeed changed, this means that you still have chances to use the History Change listener on your own or maybe the built-in GA4 functionality will take care of this automatically.

URL changes might look different based on a website you’re on. On some websites, the URL fragment changes (that’s the part of the URL after the hashmark #). On others, the URL change might look casually, like on a regular website (e.g. from /home/ to /home/contact-us), etc.

If you confirm that the URL changes, let’s move to another step.

 

Method #1. Track pageviews with GA4 Enhanced Measurement

Note:  Enhanced measurement provides a bunch of event tracking capabilities, but many of them can work inaccurately (e.g. scroll tracking), thus it will make sense if you disable all the non-pageview related tracking (scroll, site search, click tracking, etc.).

Now, let’s see if the built-in page view tracking in GA4 works for you.

In Google Analytics 4, go to Admin > Data Streams and click on your web data stream.

Then click the gear icon next to Enhanced Measurement (also, make sure that Enhanced Measurement is enabled).

Then click Show advanced settings under Page views and check if the Page changes based on browser history events checkbox is enabled. This will allow GA4 to automatically try every time the URL changes (or at least try to do so).

After that, save all the changes in GA4. In Google Tag Manager enable the Preview and Debug mode and then navigate to your single page application/website. Try navigating from one page to another.

In the preview mode of GTM, you should start seeing History Change events and their technical event name is gtm.historyChange-v2. You will be able to see it while having the GTM container selected at the top of the preview mode.

If you indeed see that, then click on your GA4 measurement ID at the top of the preview mode and check if you see multiple Page View events being sent to Google Analytics 4. If yes, then it’s good news. GA4 will be able to track pageviews of your single page application automatically and you don’t need any additional configuration.

Also, check the DebugView of GA4 to make sure that page_view events are coming with proper page_title and page_location parameters.

If you cannot see the History Change events (or the page_view events are not being sent to GA4), then go to the next chapter of this blog post.

 

Method #2. Try the History Change trigger

The most robust solution of tracking single-page applications is cooperation with a developer. No doubt. However, sometimes the developers are not available at all, so we might have to work with what we have. That’s why this method is also available as an alternative.

In Google Tag Manager, go to Triggers > New > History Change and create a trigger with the following settings:

Then we need to test if it works. Enable Google Tag Manager Debug mode. Click Preview button in the top right corner of your GTM interface (near Submit button).

If you ever stumble upon older GTM tutorials (published before the October 16th, 2020), they will tell you that an orange banner must appear in the GTM interface (when the preview mode is enabled). That is no longer true. From October 16th, 2020, the orange banner is gone.

Once you click the Preview button, a new browser tab will open with tagassistant.google.com. If it does not, read this guide.

A popup there will ask you to enter the URL which you want to test and debug. It might be the address of a homepage or it might be a specific page’s URL and then press Start.

A new browser tab (or window) should appear where you will see the URL that you entered in the previous popup. At the bottom of that page/tab, you must see the following badge:

Click (or scroll) through various sections of the single page web app (or website) to make the URL change. After the change happens, take a closer look at the event stream in the Preview and Debug console.

Did the History event appear? If yes, that’s good news! If not, skip to the chapter where I explain how to cooperate with developers

On some single page applications, you might see several History events occur at the same time. That’s why you need to answer one more quesiton.

 

When you navigate from Page A to Page B, how many History events do you see?

Some websites may be coded in a particular way that will cause multiple history events to appear at the same time in the GTM preview mode. If you face this situation, read this guide where I explain how to configure your trigger to work only with certain History Change events (and thus avoid duplicates).

 

Sending data to Google Analytics (thanks to History Change trigger)

After you made sure that History Change trigger works fine, you will have to send those pageviews to Google Analytics.

Google Analytics 4 is an event-based analytics platform. It means that everything is an event. Pageview, click, purchase, etc.

Since we want to send the pageviews every time a History event occurs, we will do that with a GA4 event tag. But its configuration depends on the URL structure of your website.

Important sidenote. On some websites, you might notice that your single page app’s pageviews are tracked properly BUT in the reports, you might notice that the title of the tracked page always belongs to the previous page. If you notice this, you will need to implement single-page app tracking with developer’s help or you can delay the History Change event.

 

If URLs of your website contains #

This part of the blog post applies to you if your website’s URL contains #, e.g. www.mywebsite.com/#/something.

Go to Tags > New > GA4 event tag and enter the following configuration. I presume that you already know what a GA4 configuration tag is, thus I won’t do an introduction here.

By itself, Google Analytics 4 (and its predecessors) are not capable of automatically tracking the URL fragments (that’s the part of the URL that goes after #). That is why we need to override the page_location. Important: you will also need to do that in all other future GA4 event tags.

What kind of variable did I use here?

One of the ways how you can pass the full URL (including fragment) to GA4 is by creating a JavaScript variable called window.location.href.

Save the tag.

 

If URLs of your website do not contain #

In the previous chapter, we overrode the page_location parameter because the URL contains the hashmark (#). But if your website’s URL has no #, then you DON’T NEED to override page_location parameter. GA4 will grab the URL properly by itself.

 

Trigger

If you have thoroughly followed this guide, you already have created a History Change trigger that listens to all events. If yes then keep it as it is. If you haven’t created it, do it now.

Assign the History trigger to your GA4 event tag for page_view.

 

Should the GA4 configuration tag automatically track the first page_view?

If you open your GA4 configuration tag (not the event tag), you will see that there is a checkbox Send a page view event when this configuration loads. Should it be enabled or disabled?

The answer is …. can you guess it? … Correct! It depends.

You should check what happens after you load/reload the page of your single-page application.

Does History event appear in the preview mode every time you reload the page?

If you reload the page (without clicking anywhere else on your website) and you see this:

…then you should disable the checkbox in the GA4 configuration tag.

If History events don’t appear immediately after you refresh the page and they become visible only when you start navigating your website/web app, then you should keep the checkbox enabled.

 

To sum up this chapter

After you follow all the steps in this section of the blog post, you should have:

1 GA4 configuration tag (that you should have created before even reading this blog post). This tag should fire on All Pages.
If every time a page is loaded, the History event occurs in the preview mode, you should disable the Send a page view event when this configuration loads checkbox.

GA4 event tag that sends the page_view event. Link this tag to the aforementioned GA4 configuration tag. This tag should use the History Change trigger.
If URL of your single page website/app contains the #, you should overwrite the page_location parameter.

 

Test the setup

After you configure and save everything, it’s time to check the setup. I briefly explain how to test your page_view tracking here.


 

Another Option: Track Single Page Applications with Google Tag Manager and Developer’s help

Most likely, you’ve reached this point because your History Change tracking attempts failed or you are simply curious to learn more.

If (for some reason) History Change trigger isn’t working for you (or there was another reason which brought you to this section), there’s another option on how to track single page web app with Google Tag Manager.

Ask a developer to activate a dataLayer.push code whenever a user navigates between pages/states of a website/web application.

Here’s a sample code snippet that the developer could use:

<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
‘event’: ‘virtualPageview’,
‘pageUrl’: ‘https://www.mywebsite.com/something/?page#contact-us’,
‘pageTitle’: ‘Contact us’ //some arbitrary name for the page/state
});
</script>

Note: Values of ‘pageUrl’ and ‘pageTitle’ parameters (in that code snippet) should be dynamically replaced with the URL (and title) of the page a visitor is currently viewing. A developer should take care of that. If the URL contains the # or question marks and some parameters, they should be included there too.

If your developer says that it’s too complicated to show the full URL, then ask for at least the page path. The rest of the URL you will need to build in GTM with variables like protocol, page hostname, etc.

Anyway, what does that code mean?

Every time a user goes to a particular section of your page, a developer should activate that little piece of JavaScript code. It indicates that a “virtualPageview” has occurred and the new page URL is https://www.mywebsite.com/something/?page#contact-us. 

Then you will use this dataLayer.push as a triggering condition in GTM (that activates the GA Pageview tag) and then send the title and page path (page over to GA.

To achieve this, complete the following steps:

Create two variables (and include them in the GA4 event tag)
Create a trigger (and assign it to the GA4 Event tag).

 

Variables

Title: dlv – pageUrl (dlv stands for “Data Layer Variable”)
Variable type: Data Layer Variable
Data Layer Variable Name: pageUrl
This variable will read the value of the pageUrl that was pushed to the Data Layer by a developer.

Create a 2nd variable:

Title: dlv – pageTitle 
Variable type: Data Layer Variable
Data Layer Variable Name: pageTitle

 

Trigger

Title: Custom – virtualPageview
Type: Custom Event
Event name: virtualPageview
This Trigger fires on: All Custom Events

 

Create a GA4 event tag

Go to Tags > New > GA4 event tag and enter the following configuration.

This time, I override two parameters (page_location and page_title). Their values are the Data Layer variables that I created in one of the previous chapters. Important: you will also need to do that in all other future GA4 event tags.

Set this tag to fire on a Custom Event trigger that you have also recently created.

 

Should you override page_location and page_title in the GA4 config tag?

Personally, I don’t see a point in that because on most single-page applications, GA4 config tag will fire sooner than the first virtualPageview dataLayer.push occurs, thus it will be undefined in most cases.

I mean, if you want, you can override them. I think you should be fine. But if you notice some negative impact because of this, let me know in the comments.

Honestly, we are all learning GA4 as we go, and maybe in the future, I will learn of a solid reason why it is necessary to override these parameters in the config tag as well.

 

Should the GA4 configuration tag automatically track the first page_view?

If you open your GA4 configuration tag (not the event tag), you will see that there is a checkbox Send a page view event when this configuration loads. Should it be enabled or disabled? It depends (just like it was in the History Change trigger’s chapter of this blog post).

You should check what happens after you load/reload the page of your single-page application. Does the virtualPageview event appear in the preview mode every time you reload the page?

If yes, then you should disable the checkbox in the GA4 configuration tag.

If virtualPageview events don’t appear immediately after you refresh the page and they become visible only when you start navigating your website/web app, then you should keep the checkbox enabled.

 

To sum up this chapter

After you follow all the steps in this section of the blog post, you should have:

1 GA4 configuration tag (that you should have created before even reading this blog post). This tag should fire on All Pages.
If every time a page is loaded, the virtualPageview event occurs in the preview mode, you should disable the Send a page view event when this configuration loads checkbox.

GA4 event tag that sends the page_view event. Link this tag to the aforementioned GA4 configuration tag. This tag should use the virtualPageview custom event trigger.
If URL of your single page website/app contains the #, you should override the page_location parameter.

 

Test the setup

After you configure and save everything, it’s time to check the setup. I briefly explain how to test your page_view in the next chapter.

 

Check the DebugView

Save all the changes in your container and enable/refresh the preview mode by clicking the Preview button in your GTM container. Then go to the GA4 DebugView.

When you load the first page of your single-page app, you should see one page_view event in the DebugView.

Check whether page_location and page_title parameters are correct and belong to the current page you are looking at.

Then start navigating your website/web app and check if the number of page_views that you see in the debug_view is correct and whether their parameters are correct.

Within the next 24 hours, you should start seeing your pageview data in Engagement > Pages and Screens reports of GA4.

 

There is no rogue referral issue in GA4

If you have some experience with Universal Analytics and how to track Single Page applications with it, you probably have heard of a phenomenon called rogue referral.

This is the result of how Universal Analytics (GA3) treats sessions.

However, the definition of sessions in GA4 is different, therefore you DO NOT need to implement any additional fixes to mitigate rogue referral (because there is none in GA4).

 

Track Single Page Web App with Google Tag Manager: Conclusion

The problem with single-page web apps or websites is that regular pageview tracking does not work. All of the necessary code is loaded once and the page does not reload during the entire user session. GA4 might be able to track pageviews of single-page applications in some cases but it definitely does not cover all the situations.

With certain configuration in Google Tag Manager (and possibly some input from your developer), you can still track them. In this blog post, I’ve explained the built-in GA4 solution and two other options on how to track single page websites: use GTM’s built-in History Change trigger or cooperate with a developer.

If you’re not sure which method to choose, here’s a rule of thumb:

If you have development resources, cooperate with a developer is a more robust option (in terms of tracking quality).
But if those resources are unavailable right now, check the flow chart I’ve included at the beginning of this guide. However, there’s still a chance that, eventually, you’ll end up asking for the developer’s input

By the way, if you found this post about tracking a single-page web app with Google Tag Manager useful, consider subscribing to my newsletter.  You’ll get various bonuses and useful stuff related to GTM.

Did I miss something or do you have any questions? Let me know in the comments.


The post Track Single Page Web App with Google Analytics 4 and Google Tag Manager appeared first on Analytics Mania.

Read MoreAnalytics Mania

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments