Saturday, 20 March 2010

Tracking scroll depth to reveal content engagement in Google Analytics

This article investigates a way to track content engagement on your site. By monitoring how far down the page a visitor to your site travels and then recording the data in Google Analytics you can discover how many of your visitors are reading your content all the way to the end.

Update

This article was written for what is now the old style tracking code. If your code looks like the snippet below then this article is for you, although you should really upgrade to the async tracking code snippet and then read the updated version of this article here.

<script type='text/javascript'>
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type='text/javascript'>
try {
var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
pageTracker._trackPageview();
} catch(err) {}</script>

Introduction

When browsing through your Google Analytics reports you will find a massive selection of data at your fingertips. You can find how many people visited a page, how long they were there, what country they were from, if it was their first visit, if they bought something from your site and so much more. If you're reading an article like this then I doubt that I need to sell you on what a great piece of kit it is.

Part of what makes Google Analytics a great package is that it provides a JavaScript API which lets you mould the functionality to your requirements.

It occurred to me that I would be interested to know if visitors to my site were reading all of my articles or if they were just bouncing in & out registering page views for content that didn't fit their needs.

I decided that a good metric to decide if the visitor has read my content is that they scroll past 90% of the total height of the page. When this scroll depth is detected I will use _trackEvent() to record the information in Google Analytics.

What is Event Tracking?

Event tracking is an alternative way of tracking user activity on your site. The normal way is by registering page views. Not every activity on your website results in a fresh page view though.

What if the user downloads a PDF, watches a video or scrolls to 90%? This is where the event tracking comes in. It allows you to register an event, put it in a category and even associate a monetary value with it.

Another approach that you might see to tracking these kinds of events is to use virtual page views. This is where you track a page view but provide Google with a non-existent url so that you can identify the event.

While this technique will let you track your on page activities it also clutters up your visitor statistics and is no longer a recommended approach. If you find an article suggesting this kind of technique then check how old it is and consider using event tracking instead.

_trackEvent

The way to track an event within Google Analytics is to call the _trackEvent() method on the pageTracker object.

The pageTracker object is part of the tracking code snippet that you will have pasted into your site (if you haven't setup a Google Analytics account yet then you should review this screencast which explains how to install your tracking code).

The method takes several parameters - category, action, label and value.

category string The category is a general category (in my code I have used "Sample Application" and "Image Enlargement" as my categories).
action string The action is a specific action for the event (such as "Download", "Click", "Play", "Vote", etc).
label string (optional) If you want to record something specific like the filename of the video being played then you can put this in the label parameter.
value integer (optional) This last type is if you want to assign a specific value to the event such as somebody you can make £5 in advertising each time somebody watches one of your videos.

A simple page tracker event might look like this:

pageTracker._trackEvent("Videos", "Play", "Cat falls off table.avi", 5);

This would assign a value of 5 dollars (or whichever currency your analytics is configured to work with) and attribute it to a play of a video called "Cat falls off table.avi".

Planning your events

I just want to pass on a bit of advice that I picked up while learning in the Conversion University. You should create a planning document which outlines the general structure of what events you intend to capture. Using a straightforward naming convention and make sure you stick to it. Otherwise you will find it unmanageable when it comes to trying to make sense of the data collected. If you are a web developer on a team then it would be a good idea to consult with the person who will be using this data before you implement your event tracking.

Taking the first swing

To start off with we simply want to be sure that the page scroll tracking is actually working. We are going to use jQuery to track the page scrolling. If you haven't every used jQuery before then you would benefit from reading some introductory tutorials but for the sake of this article please just take my word that the .ready() allows you to run a piece of code when the page has finished loading and window.scroll() allows you to run a piece of code each time a scroll is detected.

Here is the first draft:

    <script src='http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js' type='text/javascript'></script> 
    <script type='text/javascript'>
    /* <![CDATA[ */
        $(document).ready(function () {
            SetupGoogleAnalyticsTrackEvents();
        });

        function SetupGoogleAnalyticsTrackEvents()
        {
            TrackEventsForMinimumPageScroll();
        }

        function TrackEventsForMinimumPageScroll()
        {
           $(window).scroll(function(){
             var bottom = $(window).height() + $(window).scrollTop();
             var height = $(document).height();
             var percentage = Math.round(100*bottom/height);
           
             if(percentage > 90)
             {
                 alert("Page Scrolled to 90% in " + document.location.href);
             }
           }); 
        }
    /* ]]> */
    </script>

You might wonder why I have used some seemingly redundant function names in this sample. This is simply to make sure the code we are writing fits in with the layout of code using in other Google Analytics integration articles on this site. To read them you can click the Google Analytics tag at the end of this article.

So from reading through the code you will see that the following occurs:

  • Some code is attached to the scroll event of the page
  • Each time the page is scrolled the percentage variable is updated to calculate how for down the page in total the user has scrolled.
  • This is calculated by comparing how far down the user has scrolled against the height of the page.
  • The page then checks if the scrolled percentage has exceeded a certain threshold (90% in this case) and alerts the user.

Try it out. Copy the code into a page and fill it with some bogus text. An easy way to get your hands on filler text is to use lorem ipsum. Just visit this site and generate a few paragraphs of text, enough to give you a scrollbar to test with:

Don't forget to put the html / JavaScript snippet above into the <head> tag in your sample page.

Back? Did it work? Great! So now we have a mechanism to detect when the user has scrolled to a certain threshold percentage.

Duplicate events

Did you notice any problems while playing with your new toy? It seems that after you continue scrolling down the page past 90% that the page keeps notifying you, again and again. If we were tracking this by sending and Event Tracking message to Google Analytics every time then our statistics wouldn't be very accurate at all!

The solution is pretty straightforward. We need a simple Boolean variable which is set to 0 when the page loads but after the first time the threshold met event fires the Boolean is change to 1 and any subsequent events are ignored.

The code would look something like this:

var IsDuplicateEvent = 0;

function ScrollingEvent()
{
   if(ScrollThreshold > 90%)
   {
      if(IsDuplicateEvent == 0)
      {
         IsDuplicateEvent = 1;
         TrackEventInGoogleAnalytics();
      }
   }
}

This code wont compile because it's not much more than pseudo code but hopefully it does illustrate the idea.

While writing this code I originally had the IsDuplicateEvent = 1; line at the end of the method. I figured that if the Event Tracking portion caused a problem then I didn't want to count it as a tracked event. When testing this code (by scrolling down the page really fast) I still managed to get duplicate alert boxes. Moving this variable to the start of the function stopped the duplicate events.

FINAL CODE - Tracking the event and wrapping up

At this point we can take our original code sample, fold the duplicate event blocker in and replace the alert() with a genuine call to the Google Analytics API. We would end up with some code that looks like this:

    <script src='http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js' type='text/javascript'></script> 
    <script type='text/javascript'>
    /* <![CDATA[ */
        var IsDuplicateScrollEvent = 0;

        $(document).ready(function () {
            SetupGoogleAnalyticsTrackEvents();
        });

        function SetupGoogleAnalyticsTrackEvents()
        {
            TrackEventsForMinimumPageScroll();
        }

        function TrackEventsForMinimumPageScroll()
        {
           $(window).scroll(function(){
             var scrollPercent = GetScrollPercent();
           
             if(scrollPercent > 90)
             {
               if(IsDuplicateScrollEvent == 0)
               { 
                 IsDuplicateScrollEvent = 1;
//                 alert("Page Scrolled to 90% in " + document.location.href);
                 TrackEvent("Content Engagement", "Scrolled To 90%", document.location.href);
               }
             }
           }); 
        }

        function GetScrollPercent()
        {
             var bottom = $(window).height() + $(window).scrollTop();
             var height = $(document).height();

             return Math.round(100*bottom/height);
        }
                                
        function TrackEvent(Category, Action, Label)
        {
           pageTracker._trackEvent(Category, Action, Label);
        }     
    /* ]]> */
    </script>

As you can see I have refactored the scroll percentage out into its own method just to make the code a bit cleaner to read.

I have also left the alert() code in there but just commented it out. This is because it can take up to 24 hours to see tracked events actually appear in Google Analytics so it's handy to use it for one final check as you put the code into your site.

Further reading

For further reading on Google Analytics integration techniques you can browse the Google Analytics tag on this site:

The official documentation page for event tracking is available at here:

kick it Shout it

8 comments:

Anonymous said...

Just what I was looking for! Trying out this script as week speak.

Thank you for sharing

masparasol said...

Thanks for this. I found I had to put a close javascript tag on the first line for each code example. Maybe you omitted this?

Otherwise, I got the popup box to work, but cannot get the results in Analytics.

Is there anything we have to do on the Analytics site to get this to work?

Where can we go in analytics to see the scroll report?

Thanks!!!!!!!!!!!!!!!

rtpHarry said...

@masparasol: thank you for your feedback. I checked my other tutorials and they all seem to have the self closing <script /> tag which as you have pointed out is incorrect and should actually be <script></script>.

If your code is not working then it might be because this article is out of date. If you look in this article then you should find the new way that Google Analytics expects you to use the API.

Also you will have to wait 24 hours before anything shows up as Google Analytics is not a realtime reporting engine.

rtpHarry said...

@masparasol: just wanted to say that I have updated all of the articles. The code has been taken directly from code I have written into my blog template and it seems blogger has been changing my tags into self closing tags. Thanks again for the heads up!

masparasol said...

Hi rtpHarry,
Thanks for the reply and the updates.
I am trying the code again, and trying different ways to track scroll. The popup works, but nothing seems to be getting fed to analytics. (It has been more than 24 hrs)
Does this exact code work for you?

I also have some event code that functions with onclick. It is working now but seems spotty.

To answer my other concern, these events can be found in Analytics by going to the Contents tab, and then click on the Events tab, of the left side bar.

RE: Analytics needing 24hrs. It might for some things, but I have got events to display in less time, and you can certainly see pageviews with almost no lag! Just change the date on the calendar to the current date. At least that works for me in the Pacific Time Zone.

Thanks again for the help with the code.

masparasol said...

IT'S WORRRKINGGG!!

Yeah! I got the code to fire through to analytics. FYI: It took analytics ~20 minutes to report the event.

I think changing to function to
_gaq.push( is what works.


W00T! w00t!

Anonymous said...

Is this scrolling fuinctionality also working for Asynch code?

rtpHarry said...

@anonymous: An updated version of this article is scheduled to be posted tomorrow at 6pm UK time. In the mean time you can follow the tip in this comment to get it working for the async snippet