For the uninitiated, single page applications (SPAs) are web apps or websites that load a single HTML page and dynamically update that page as the user interacts with it. They’re becoming quite popular with developers because of the advantages they have to offer (responsiveness, performance etc). Gmail and Twitter are popular examples of single page applications. Dan Pupius, the head of engineering at Medium also wrote about them here .
In traditional websites, when a user navigates from one page to another, the associated HTML, Javascript, CSS etc is rendered each time a new page loads. In single page applications, all of the necessary code is loaded once and changed when needed in response to user actions. The page does not reload during the entire user session. The URLs might change but that is to give the perception of logical pages. Let’s say your pages look standard across the site (same header, footer and body) and in every new page the content and a few buttons change. The code for all the standard elements loads once (when the user first lands on your website) and any new content is loaded dynamically via AJAX.
Because of the manner in which SPAs work, they pose a challenge when it comes to implementing tracking snippets. A lot of javascript snippets won’t work as expected with SPAs because they’re written for traditional websites where the tracking snippets can detect when a new page loads and hence fire as set. But in SPAs, since the page technically loads only once, so do the snippets (unless the user manually refreshes the page). If these snippets aren’t reinitialised on a user action, they cannot check for, for example, a URL change and hence not function as you might have programmed them to. A lot of companies like Optimizely & WebEngage have adapted their snippets to work with SPAs. Hotjar has it on it’s product roadmap (On a side note, what a brilliant product). Google Analytics also provides a way to track SPAs in their documentation.
Another way to implement Google Analytics in your SPA with little developer support is via using Google Tag Manager (whose awesomeness I am just getting introduced to). You will require basic working knowledge of both GA and GTM to understand the described procedure.
The goal is to alter what Google Analytics perceives is a pageview and hence make sure it’s recording pageviews for, what I will call for the purpose of this article, virtual pages. Here’s how you can do it,
- Ensure Google Tag Manager is properly installed on your website. You can find instructions on setup and installation here .
- Log in to Google Tag Manager and click on ‘Variable’ on the left menu bar. Create a dataLayer variable (more on these later) called virtualUrl. Don’t set a default value.

There are some guidelines wrt naming variables, you can read about them here.
- Click on Triggers and create a new Custom Event trigger called 'Virtual Pageview'. Set the filter to 'event' contains 'virtualPageview'.

- Next, get a developer to initialise a dataLayer on your SPA (or DIY if you can!). GTM needs a place to store the information you pass to it. It uses a javascript array for this purpose and chooses to call it the ‘dataLayer’. Once you’ve pushed information about your site or a visitor into the dataLayer, you can pass it to various tools using GTM, one of them being Google Analytics. There’s tons of cool stuff you can do with GTM and dataLayer but I’ll save all of that for a separate post. (Everything you need to understand what the dataLayer is all about is written in this post)
The developer also needs to create a function that pushes an object containing two properties into the dataLayer on every URL change. It'll look like this.
function() {
dataLayer.push({'event':'virtualPageview', 'virtualUrl': <virtual url>});
}
Here <virtual url> is your code to pull the page path. Make sure that both these properties are passed as a single object in the same dataLayer.push method. - To test if this implementation is working fine, turn on preview mode in Google Tag Manager and check the Data Layer tab.

- Create a new tag in Google Tag Manager. Select Google Analytics from the list of integrated tools. Add the tracking ID is the specified field. Now the fun part. Under 'Fields to set', set the value of 'page' to Virtual URL (the curly braces indicate it's a placeholder).

Under 'Fire On', select 'More' and then select 'Virtual Pageview' from the list of triggers that show up.

This will fire the tag every time the dataLayer is populated with event:virtualPageview and the page will be set to whatever value is stored in ‘virtualUrl’ property at that point.
- To test whether you're passing the correct data to Google Analytics, you can use the GA Debugger Chrome extension. All you have to do it switch on the extension and monitor the Console tab in Developer Tools.

If everything looks good, you're set!
Get Aamna Khan’s stories in your inbox
Also...
- You can read more about understanding Variables, Tags & Triggers here.
- You needn't reset the dataLayer each time the URL changes as you can keep pushing new values for the same variable and GTM will pick the latest value.
- You can also use the 'Page Path' variable (which is a built-in page variable in GTM) instead of using virtualUrl but it might not track some pages.
Shoutout to the folks at Optimize Smart. Discovered the website while reading up on this subject. Amazing resource on google tag manager, google analytics and a bunch of other stuff.
Thanks to Sameer Parwani, Manas J Saloi and Girish Kamath for reading drafts of this article.
Originally published at www.linkedin.com.
EDIT: If you found this post useful you might be interested in reading my follow up post on the topic.


