Tracking outbound links? I bet you only measure 70 percent

A lot of site owners want to track outbound links so they can see how often they are clicked. It's also useful to see when and where people left your site. Google Analytics knows the exit time of your last page, where in normal cases the last visited page is not counted in the spend time on site/page.

But, there is a big but. A lot of outbound link tracking is done like this:

<a href="http://andrescholten.nl" onclick="trackClick(this)">Nice site</a>

And this is what happens when you click on this outbound link:

  1. The onclick is executed first
  2. The trackClick function generates an IMG element with a URL that points to the Web Analytics vendor
  3. The onclick function is handled and the browser starts with the href part

And then the race starts:

  • The tracking pixel is requested from the Web Analytics vendor
  • The browser kills all activity and opens the URL in the href attribute

But we can't tell which one is first. A small delay on the Web Analytics vendor side is deadly for the tracking, often the pixel request is killed by the browser. You can see this in a simple tool that shows you all activity in your browser. Because Yoasts' post is was the trigger to blog this I will use his site as an example.

Take a look at his Clicky outbound link tracking post. It has an outbound link in the first sentence. And this happens when I'm clicking it:

The first two lines are the main Clicky script with all tracking functionality and the basic pageview measurement. The third line is the outbound link tracking: in this case the tracking is send. The line is red because the browser stops waiting for the response, but that isn't necessary for the tracking. Sometimes this line isn't generated and no tracking is done...

A solution

In the post title I mentioned 70%, but that's merely a guess based on what I have seen in cases where I solved this. After implementing a little timeout before the link opens we saw a lot more outgoing links being measured. I already mentioned the solution: a little timeout to give the tracing some time to execute before the link opens.

But there are a few caveats using this technique:

  • Using "window.open" triggers the popup blocker of Internet Explorer 9+. That's because the link is opened with a script in stead of a user initiated click. We have to use location.href to prevent that from happening.
  • Using "location.href" doesn't pass on referrer information in Internet Explorer 6, 7 and 8. External site won't see traffic coming from you.

This is de jQuery code I use right now to track outgoing links:

if(typeof jQuery == 'function')
{
jQuery(function ()
{
jQuery('a[href^="http"]').click(function (e)
{
var url = this.toString();
if (url.indexOf(document.domain) == -1)
{
_gaq.push(['_trackEvent', 'clickouts', jQuery(this).attr('href').replace(/https?:\/\/(.*)/,"$1")]);
var target = jQuery(this).attr('target');
if (target == "") { target = "_self"; }
setTimeout(function()
{
var a = document.createElement("a");
if ((!a.click) || ((jQuery.browser.msie) && (parseInt(jQuery.browser.version) > 8))) {
location.href = url; // for chrome and IE9+, target is lost
} else {
a.setAttribute("href", url);
a.setAttribute("target", target);
a.style.display = "none";
aElm = document.body.appendChild(a);
aElm.click(); // for IE6,7,8 to pass on referrer
}
}, 50); // 50ms should be enough timeout
}
e.preventDefault();
});
});
};

Is this the best way to track outgoing links? For what I've seen this is one of the best and most reliable approaches. But I'm happy to receive additions that makes it even better.

Ps. In this example I used Google Analytics to track outgoing links, but you can change that part to whatever tracking you want.

Update

Eduardo Cereto proposed to use the mousedown event without an additional timeout. I tested this on several sites and it looks like the most reliable solution right now. The code is much easier also:

jQuery(function ()
{
jQuery('a[href^="http"]').mousedown(function ()
{
var url = this.toString();
if (url.indexOf(document.domain) == -1)
{
_gaq.push(['_trackEvent', 'clickouts', jQuery(this).attr('href').replace(/https?:\/\/(.*)/,"$1")]);
}
});
});

Click to activate social bookmarks