A better approach to tracking single-page sites in Google Analytics

Humans. If we don't shoot ourselves in the foot every now and then we are not happy. It took us years to get rid of the scourge of Flash sites but someone had to make single-page websites popular. Now that I've clearly established my love for these kind of sites, let me provide further explanation.

better approach to tracking single-page sites in Google Analytics


My major concern about them is measurement-related, I'll go over it in a minute. But there are some other strings attached that are no less relevant to discuss.


If you have a basic understanding of what SEO means, you already know that having all of your content under one single URL does you no favours while trying to improve the quality and quantity of your organic traffic, or how Aaron Bradley puts it, your Digital Presence Optimization. There are not tricks for that, you need more content distributed in pages having unique URLs. Single-page sites go in the opposite direction!

Performance-based marketing

PBM does its retargeting from cookie pools. As the whole site is one URL, it is not possible to generate content-specific cookies (let's say a cookie that is created when user visits a product description page) so the loss of potential revenue could be thousands per month.

Even if we manage to have clean URLs (not including #! for sections by using the pushState() method) by panel it's just one HTML document that makes retargeting impossible. I would love to be wrong here.


Tempted to say there aren't any but to be fair, they do exist and here are the only ones I could find.

Limited amount of content

Your site is pretty much an online version of a business car plus some fancy effects with not much content to offer and a single page cuts it. That makes a case for a one-page site. Fair enough.
Example http://kathylovesairbnb.kythe.co

UX / message control

From a user experience point-of-view there is some merit to this type of layout. Single-page sites can sometimes be more effective at communicating a story. There are more options to create a captivating and immersive experience for the viewer which, if done well, can in turn inspire a user into action. The one-page layout can also help in message control. You're guiding a viewer down a specific path which as a website owner almost forces you into providing information in a more seamless, clearer manner.

Those are not my words, but those of a workmate. I'm genetically incapable of embellishing an argument that much to make it sound more compelling but he has a point.
Example http://makeyourmoneymatter.org

I have to say that some of the sites that EA's Pulse team puts together make decent use of the concept of 'long paneled' page, I mean only at some sections of large sites (so it is not really a single-page one) where money is not at stake and more of that 'message control' is required.
Example http://www.easports.com/fifa/ultimate-team/features

Parallax scrolling and AngularJS

Those two fellas are partners in crime when it comes to making single-page sites popular. The first one is nothing without a single super long HTML document and the second one, well, don't start me talking about AngularJS and analytics, it deserves a complete new post that I'll try to write soon if Diazepam helps enough because that framework is getting on my nerves.

Bye-Bye bucks

Can you imagine prevent adding thousands of dollars to monthly revenue because someone convinced stakeholders that single-page sites were the latest in the interwebs? Not sci-fi, it happens.

In sum, there are situations where single-page sites could be justified but if your web has a clear objective other than just telling a story nicely (as it could be making money directly or indirectly) and you are going to invest significant amount of money to create and promote it good luck with ROI there amigo!

Typical tracking approaches I've seen so far

Single-page means single-pageview sites 99% of the time

Worst case scenario. Example: http://www.spaceneedle.com/home/. Scroll as much as you want, just a single pageview is fired. No need to explain what that means from a measurement standpoint. A total fail only one step behind of not having tracking at all.

Tracking panels as pageviews no matter what

This site mentioned before http://makeyourmoneymatter.org/ tries harder. They fire more than a single pageview. In fact, a new pageview is fired every time one of the panels hits the top border of the viewport. But if you scroll top-to-bottom, all pageviews are fired even though you haven't seen any of the content in between. Does it solve the problem? I don't think so. It collects more garbage than meaningful data.

Interesting how it works here http://www.battlefield.com/hardline. Slightly better, I would say, from a data collection point of view. Because those panels tend to snap automatically the top of the viewport when scrolling, the GA tracking is not the agent solving the problem.

Tracking panels as events

Similar to the previous point but instead of using virtual pageviews it fires events instead. Wrong. Events are meant to catch user interactions in the context of pages, not a substitute of them. Even worse, that also leaves legit events properly tracked without the context of the page in which those events occurred.

Using page scrolling instead

Tracking the web user's scrolling percentage provides a different type of data. What happens to those percentages if page length changes because more content is added or removed? Comments or new content sections, for example. 25% still be 25% but the content associated will change with time.

Not a good solution either as percentages tell us nothing about the content they are trying to refer to.

There is a very popular and superb Google Analytics plugin to measure page scrolling coded by Rob Flaherty that also tracks panels and other great features. I honestly don't think it solves the issue we are trying to tackle today, unfortunately. Rob has two more plugins that you might want to explore as they could help with other situations you might have with your tracking.

So how can we improve single-page sites measurement?

Let's face it, scrolling up and down panels of content that we would consider relevant enough to be a page will never be as precise as navigating traditional web pages with different URLs (different HTML documents). This has been driving me nuts for a while so I've invested spare time trying to find the right approach. My old time mate Alejandro Scott gave a hand to polish and finish the code as he is thousand times faster and better than me on that. This is the outcome.

It's configured to fire a virtual pageview every 3 seconds as you will notice in the red layer. A bit too long but for demonstration purposes it works fine. You can also open Chrome's console if using Google Analytics Debugger to see how it fires pageviews to GA besides the simulation in that red layer.

As mentioned before, there are many JS libraries out there. I believe this document to be superior due to several reasons that, when working together, increase accuracy to an admissible level:

(Virtual) Pageviews, not events

The likely reason why those libraries tend to fire events instead of pageviews is they are usually coded by programmers, not analytics guys. These programmers don't quite get how all the different types of data collected relate to each other and what the best practices are. I don't blame them, they should receive better instructions from their analytics people on how the logic of their code must work.

Inside analyticsStuff() function you can define what we want to fire though. This is also the place to decide if you want to fire classic GA virtual pageviews or Universal ones.


Cornerstone of all this rant. There is a variable waittoVPV than can be configured to determine the number of seconds before a virtual pageview is fired. That solves the problem that happens when scrolling quickly up or down and firing pageviews for all the panels in between when, in reality, we simply don't see them. 'See', meaning 'giving them a minimum of attention that we could consider a real pageview' (2 or 3 seconds is fine). That will keep nonsensical pageviews to a minimum, considerably increasing tracking accuracy.

Hot area

Another element (besides timing) that adds imprecision to the mix is when, in user action terms, the pageview should be fired. While scrolling, if the top border of the panel gets close to top border of browser's viewport but not touching it, the pageview is not fired even if I really see the whole content of that panel. Usually it only works when going across the border.

To mitigate that undesired effect we have enabled a ‘hot area' that spans from somewhere below the top border (variable marginBottom) to somewhere over it (variable marginTop). Any panel's top border that enters that hot area is tracked as a pageview, giving some room for inaccuracy in its position. You can scroll a bit up or down but if you keep it inside the hot area the pageview will be fired once.

tracking single-page sites in Google Analytics

Variables marginTop and marginBottom can be configured to fit your page's 'hot area' in a way that better serves your page needs.

In the working example the semi-transparent red sticky layer you see at the top represents the hot area although only the visible part of it under window viewport's top border (for obvious reasons).

Independent navigation method

Some JS libraries try to track pageviews based on navigational elements being clicked (some programmers call that deep linking, don't ask me why). This frequently increases inaccuracy too.

In this solution, even if the user lands on the page by following a link with an anchor like some-page.html#about the tracking works as expected -- only firing a pageview for the right panel.

Virtual pagenames sent GA can be set independently

Divs (<div>) acting as panels can have a data attribute attached (data-vp-name="") where the URL capturing the pagename can be set. Most of the JS plugins out there grab the name to fire from a div's ID. This is usually set by programmers and does not conform to the URL naming convention we have so I prefer not to interfere with their stuff while having room for mine. Everybody happy.

To make it clear, in this case -> data-vp-name="/panel-a" is what will be sent to Google Analytics, with the report value being '/panel-a'.

Hint: the data-vp-name value of the top panel should match the real URL of the page to keep numbers as accurate as possible. For example, if the single page lives here http://mysite.com/features/, the first panel data attribute should be data-vp-name="/features/".

Note. As you might have noticed, when you land on the example linked before, no pageview is fired. This is not a bug, I'm just counting on your default pageview fire by your analytics implementation itself.

Identifying panels to track

Well, this may be obvious, but I wish to state that there is a variable panelClass that sets which divs are considered the panels to track.

Feel free to download the code and use, tweak or improve it as much as you want. This implementation requires jQuery as usual.

Your constructive criticism is always welcome.
Happy tracking!

Thanks again Heather Anderson, Origin's awesome frontend developer, for proofreading.

Nov 10, 2014
Written by:
Filed under: Technical Analytics

Nov 14, 2014
Posted by:
Rob #1


Thanks for the Scroll Depth shout-out :) There are some interesting ideas here but I disagree about redefining Pageviews instead of using Events. The reason JS libraries use Events for tracking in-page activity is that that's exactly what Events are for. Scrolling to a particular panel, for example, is an event.

For single-page sites, I think the solution is about accepting that we're moving to a post-pageview world and that's ok! Instead of redefining the Pageview to make it match the old model, we should embrace new metrics that better suit the new model.

Nov 14, 2014
Posted by:
Ani Lopez #2

Hi Rob, thanks for sharing your thoughts and code.

Interesting how you put it: scrolling to a particular panel is an event. I agree in the sense of clicking a link to navigate to another page is also an (user) event but we don't (usually) track those as it's not very relevant data. We already know user navigated from page A to B clicking at the link that enables that.

In the new world of single-page sites, scrolling is the new link-clicking to navigate chunks of content, that is why I don't consider them relevant enough, from a user event perspective, to be tracked while attention paid to content is still and will be relevant. Pageviews tell what content and set the context for available user events.

True that we need to move forward from pageviews centric measurement but I don't think that get us into a post-pageview world.

In any case at the end of the day, one way or the other, if you manage to pull the data you need for your analysis, we are all good here.

Jan 24, 2015
Posted by:
Sonia Pitt #3

Well guided and information rich post. And I mostly agree with you. From the SEO stand point I will always oppose these single-page, parallax or infinite scroll sites because they are not SEO friendly (mostly) and tracking the parameters on GA for these types of site are simply nightmares.
But the approach you mentioned above, can be tested on couple of sites to measure and track the important metrics.
Thanks for sharing your knowledge.

Oct 20, 2015
Posted by:
Brian Katz #4

Great points Ani and an excellent solution to a slippery problem.

Whatever happened to all the learnings against "below the fold"?

If one is tracking user interactions, like simply scrolling, events are appropriate.

But when one is measuring content consumption, pages are the correct unit of measure and Virtual Pageviews the only method of providing those dimensions and metrics.

They also provide time on page metrics, page bounce rates, exit pages and page exit rates.

The only thing one has to keep in mind when analysing the data is that pages are far more fluid - but that's just another problem with single-page/endless scrolling fads. The techniques provided here by including timing, go as far as I think one can in tracking that fluidity solidly

Thanks Ani

Feb 05, 2016
Posted by:
Joe #5

Love this approach. I am using this on a site that is not a 1-page site, but has a lot of long pages with multiple sections. And I want to know which bits of content are consumed most on these pages. So thank you.

I do have a question, do you see any issues with implementing this using google tag manager?

I am going to set this tag to fire after the main analytics tag.

Again, awesome solution.

Feb 05, 2016
Posted by:
Ani #6

Thanks Joe.
Yes, I've used that in the same scenario, not 1-page site but site with very long pages having multiple sections.

I have implemented it using Tealium Tag Manager and I see no problem doing it using GTM. Haven't tried though.
Feel free to go ahead ans try, of course.

Feb 09, 2016
Posted by:
Joe #7


I am having some weird issues trying to implement this. A.k.A I am not doing it right. Should I fire it in a separate tag or do I have to merge it into one main analytics tag?

Any screen shots or further implementation tips you could give would be out of this world.

Thank you again.

Feb 10, 2016
Posted by:
Ani #8

To be honest I have no idea because I have not tried to use GTM for that purpose. Whenever I have a moment I'll do it and email you with the solution

Have your say
twitter @anilopez

Articles I write for other sites

Analytics Tribulations Of An SEO

The art of measure is never easy but when it comes to SEO it's even worst

Challenges of Spanish Language on Search Marketing @ Multilingual Search

'Standard Spanish' is something that I don’t buy into when it comes to international scenarios. I'll explain to you why and some tips to start facing correctly your Spanish strategy.

Handling Multilingual Sites for Humans & Search Engines @ Bruce Clay Blog

The logic behind the scenes to show all content to bots and the right language to users

Mobile detection issues & Google Instant Previews @ Cardinal Path blog

Mobile web represents the bigger headache ever for those wanting to target the small but growing audience they represent nowadays. check your Instant Previews for possible indexation issues.