In the last few years, there has been a large increase in “single page websites”. These websites allow a user to access all content on one page by scrolling vertically or horizontally. There are even websites dedicated to showcasing such websites (e.g. One Page Love).
This presents an issue within the analytics world. Looking at the reporting within a web analytics platform, it would only show top level metrics. We wouldn’t be able to truly see how a user progresses through the site. We also wouldn’t know what content they are consuming. And if we don’t know that, how do we improve the website?
So how can we tag our pages in such a way to get access to this data? We can rely on our old friend, the virtual pageview. By splitting the single page into “sections”, we introduce a layer of segmentation which can be tagged as individual virtual pageviews. Ideally this would be included in the design of the website, with individual HTML elements being used for pieces of content.

Key Concepts

Minimum percentage of screen covered by element

With a single page site is that multiple elements may be visible on a page at any given time. We could track the page only when the element is fully visible but that is not necessarily how this content is consumed. It could be possible for a user to be reading an element which is only partly visible on the screen.
For this reason we introduce a variable, named – funnily enough – minimumPercentageOfScreen. This will allow us to compare the amount of screen taken up by the element.
By using this notion, rather than a notion of “how much of the div is visible”, we protect ourself against elements which are far larger than the screen.

When do we check this percentage?

In our mind, there are 3 key times when this percentage should be checked:

  • On load: $(window).load
  • On scroll: $(window).scroll
  • On resize: $(window).resize

We hope these are self explanatory, but if you are confused or feel we’ve missed any events, please leave a comment below!

How do we choose what to track?

So how do we know what elements we should be checking against and eventually tracking? Our simplest solution is an array, which contains ids of the elements we want to track. For example:
var idsToTrackAsVirtualPageviews = [“div1″,”div2″,”span1″,”img3”];
Within our method called on the above events, we can then iterate through the elements required to check their percentage, as such:
$.each(lypn_idsToTrackAsVirtualPageviews, function(index, id) { //Your percentage check here }

What counts as a “pageview”

So, we have our minimum percentage, and if we have the percentage of screen currently taken up by the element, we can track the element as being “viewed”.
But… Has it been viewed? A lot of single page sites have navigation buttons, clicking these will often move the scrollbar quickly down to the appropriate section. Surely the user hasn’t consumed any of the content passed over in this case? Correct.
Now it is very tempting to introduce new notions. A timer, for example, would allow us to track the amount of time the user views the element for. When the timer reaches a “minimum time spent viewing content” marker (say, 2 seconds), we fire a virtual pageview. Unfortunately this introduces new complexity – why 2 seconds? Why not 5 seconds?
But hang on… Does this actually matter? We think not. This complexity comes at a cost. You will now have a background process running to check the status of your timer. In our opinion, this is simply too intrusive into a website design. This is before we get into the argument of who decides what time limit a piece of content needs to be “viewed”.
Our view is simple. Once the content has filled the screen passed our threshold, fire a virtual pageview.

“Leaving” a virtual page

The next problem is a result of the above three implementations. Imagine we have an element in our window and we were to resize the window (or scroll across the element if it’s suitably large), on each event, assuming the element is still “in view”, we are going to fire a pageview. Clearly this is not correct.
The solution? We recommend an array of “last tracked elements”, when we initially track the element, we set:
lastTrackedVirtualPage[id] = true;
When the element is no longer in view, we set: lastTrackedVirtualPage[id] = false;

Pagename prefix

One last small note: we also introduced a pagename prefix, this is appended before the div id. This will allow you to see which page the “sections” are part of. This should obviously be changed for each real page.
We hope you have enjoyed our blog laying out the key concepts of tracking single page websites, we welcome your comments below.