Time-On-Page Goals in Google Analytics & Website Optimizer

Today the Website Optimizer team introduced some new features that will make Optimizer much easier to use. I’m going to defer to the guys at GrokDotCom for coverage on the new features. They got their post up pretty fast and included a snazzy interview with Tom Leung (the Website Optimizer product manager). Please take a moment and check it out.

I’d like to highlight a seemingly minor update to the WO documentation that opened my eyes. Along with the new product features, the WO team published a simple tutorial about how to track time-on-page based conversions. This method can be used to create conversions based on how much time a visitor spends on a page.

How much TIME!Why is this important? Some conversion activities have nothing to do with completing a process. Some conversions measure how engaged a visitor is with a website. While there are many ways to measure engagement, and many different opinions about what engagement is, time spent reading a certain page is one way to measure engagement.

Anyway, the method that the optimizer team published in their support doc can be used in Google Analytics to create time-on-page goals. The secret to the tracking is translating how much time a visitor spends on a page into a pageview. Remember, goal tracking in Google Analytics is based on a pageview. We need to create a pageview that indicates the visitor has been on a page for a certain amount of time.

How it Works

To translate time on page to a pageview we use a nifty JavaScript function called setTimeout(). This function will ‘do something’ after a specified interval of time. We can use setTimeout() to create a pageview after some period of time has elapsed. How do we create pageviews in GA? With urchinTracker().

Here’s the code that will create a pageview after a certain amount of time:

You’ll notice that there are two parts to the setTimeout() function. They’re separated by a comma. The first is urchinTracker(). That’s what will create the pageview after a certain amount of time. The second part is the number 20000. That’s the amount of time that setTimeout() will wait before executing urchinTracker() and thus creating the pageview.

The time is in milliseconds. 1000 milliseconds equals one second. So 10000 milliseconds = 10 seconds.

Place the code, below the standard GA page tag. Once the page loads the timer will start. When the time limit is reached the urchinTracker() function will execute and a pageview will be created for the value passed to urchinTracker(). I’ve used a couple of Google Analytics variable to define the name of the pageview.

udl.pathname is the part of the URL that occurs after the domain extension (.com, .net, etc.) and before any query string parameters (which usually start with a question mark).

_udl.search is the list of query string parameters that appear after the path.

The code will create a pageview for a fictional page named ‘/read-pages’. Part of the fictional page URL will be a query parameter named ‘page’ that stores the name of the page that the visitor was on when the pageview was executed. This setup gives you a lot of flexibility when setting up the goal.

Here’s how the goal would be setup:

Goal Settings for Time on Page Goal

And here are some additional settings I’ve added to this goal:

Additional Settings for Time on Page Goal

The goal is defined as a regular expression. So any pageview that matches ‘/read-page\?page=’ will contribute to the goal total. Using this setup you can create one generic goal called ‘Read Page’ and then use the Goal Verification report to segment the conversions and identify which pages people actually read.

An Example

Let’s say we want to track how many people stay on the following page for 3 minutes:


First we need to translate minutes to milli seconds:

3 minutes = 180 seconds
1 second = 1000 milliseconds
3 minutes = 180000 milliseconds

Now we’re ready to add the code to the page. Remember, it must go below the standard GA page tag:

After a visitor views the page for 3 minutes the code will create a pageview for:


And a goal conversion will follow.

A Note About Website Optimizer

Obviously this technique will work for tracking conversion in Website Optimizer. The implementation is slightly different. You need to include the account number in the SetTimeout() function. The reason is that the GA code might have a different account number than the Website Optimizer.


I can’t believe that I didn’t think of this method before. :) Thanks WO team for posting that very cool article.

Now, what about number of number-of-visit goals or time-on-site goals? I’ve got the number of visits goal tracking figured out and I’m working on a generic time on site. Stay tuned.

Be Sociable, Share!

    Like this post? Sign up to get posts delivered to your inbox.


    1. says

      Excellent article.

      What if you set this code up on several pages on your website. Will a session that triggers e.g. three of the special calls to urchinTracker() result in one or three conversions?


    2. says


      Thanks for the link, but thank you most of all for this top-notch analysis. This type of walk-through is very helpful for folks who are already a bit intimidated by testing.

      We keep hoping to have a GWO competition for Grok readers, but we haven’t yet had any takers. (*sigh*) Hopefully, as more people get their feet wet, that attitude will change. :)

    3. says

      Hi Robert,

      Thanks for the kind words. I had no idea you guys were running an optimizer contest, what a great idea. Since we started working with Optimizer we’ve found that it’s difficult to convince clients to engage in testing. I think we’ll see more interest in testing as more and more people start to realize that testing is a key part of the web analytics process.


    4. ramy says

      hi Justin,
      it is a piece-of-art tutorial, but i’m wondering if there are missing parts in the code published.
      i reviewed it twice (eg, no place to put the amount of milliseconds)

      another point, i think could make use of the artificial pageviews this code creating to include it in a dedicated profile (and exclude it from the main one), this will give me the total number of read pages more than X seconds (not only one conversion per visit)… am i right?

      thanks in advance for ur help

    5. says

      Hi Ramy,

      It appears that some of the code was truncated, SORRY! I updated the post and corrected the formatting issue.

      Creating another profile is a good idea. This additional pageview will artificially increase the number of pageviews for the site.

      Thanks for reading and thanks for the comment.


    6. says

      Hi Justin,
      i am currently using the WO code to track time on page but seem to get results back saying that every visitor has converted and stayed more than 20 secs?? I know this isn’t correct, can you tell me where i might be going wrong? Appreciate your help, Patrick Henry

    7. says

      Hi Patrick,

      I would check the JavaScript code that you’ve paced on your pages. If WO is reporting 100% conversion rate then the JS must be executing and triggering the conversion code. Make sure that your conversion from seconds to milliseconds is correct.

      Hope that helps and thanks for the question.


    8. says

      Hi Justin,

      Awesome Tutorial! I have used it to create a time on site tracking goal by passing a session variable that contains a running millisecond total. Thanks!

      I could also use the code for the new tracking script. Any idea when you will have this ready?

    9. says


      Unfortunately you need the extra pageviews to calculate the goals. What you could do is exclude all of the extra pageviews from a duplicate profile to get an accurate count of pageviews.

      Thanks for the question,



    Leave a Reply

    Your email address will not be published. Required fields are marked *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>