Thursday, December 9, 2010

Link Tracking using jQuery and the Google Analytics Asynchronous Tracking Code

The Google Analytics tracking code is triggered when pages that include the code are called. But what about when users request PDFs and other documents that aren't web pages or click on links to external web pages on other websites?  How do we track these events also?

Here is some jQuery you can add to your pages that will allow you to track when people click on these links.  You will have to add the Google Analytics Asynchronous Tracking code (found here: and add jQuery to your page (see here: to use this code:



  href = ($(this).attr('href') == undefined) ? ('') : ($(this).attr('href'));
  href_lower = href.toLowerCase();
  if(href_lower.substr(-3) == "pdf" || href_lower.substr(-3) == "xls" || href_lower.substr(-3) == "doc") {
   _gaq.push(['_trackEvent', 'document', 'download', href_lower.substr(-3), $(this).text()]);
   _gaq.push(['_trackPageview', href]);
  if(href_lower.substr(0, 4).toLowerCase() == "http") {
   _gaq.push(['_trackEvent', 'external_link', 'open', 'href', $(this).text()]);
   _gaq.push(['_trackPageview', href]);
  if ($(this).attr('target') != undefined && $(this).attr('target').toLowerCase() != '_blank' && href_lower.substr(0,10) != "javascript") {
   setTimeout(function() { location.href = href; }, 200);
   return false;



So, the example above will track clicks on internal links opening files with the extensions pdf, xls, and doc and will categorize them in your Google Analytics event tracking reports as "documents".  It will also track outgoing links (links with URLs beginning with "http") and categorize them as "external_links".

If you need more categories, add more if statements.  In the method above I create one click event that is attached to every link on the page, rather than just attaching specific events to the links that require them.  If a link satisfies more than one criteria (e.g. it's a link both to a PDF, and it's on an external website) then both events will be created.  In the end I thought this approach was probably more customizable and efficient overall, especially if there are several event categories.

The setTimeout bit is to allow links that replace the page content (i.e. regular links) a moment before calling the page; so that the GA function has time to execute before opening the page. Be careful when using plugins like Fancybox; add links to such plugins to the exception list in the condition wrapped around the setTimeout function as these functions remove the href attribute and the combination of that and the setTimeout can cause unpredictable behaviour.

You may want to track events for clicks made by specific links like the nav or featured content.  You can achieve this using a similar method:

$("#main_menu a").mouseup(function(){
if($(this).attr('href').toLowerCase() != "javascript:;" && $(this).attr('href') != "#") {
_gaq.push(['_trackEvent', 'main_menu', 'open', $(this).attr('href')]);

Change the ID in the yellow to whatever you call the container that your menu is kept in.  I added the check for JavaScript:; and # just in case there are links that don't open pages (e.g. links that reveal further options).

Leave comments if you have other suggestions for mixing jQuery and GA for better tracking.


  1. Very cool!

    Couple super quick cleanup notes:

    You should probably run this AFTER your Google Analytics code, which should be at the very bottom of your document, which means you don't really need the $(document).ready wrapper.

    Careful on making href and href_lower global vars, might wanna declare those.

  2. Actually, I think you would need $(document).ready(), because with the asynchronous GA code, a lot of people are now putting it in the <head> of their pages (which Google now recommends), plus GA then basically just loads "out of the band" from the normal page. So, whether your link code is before or after the GA call, it doesn't really matter. That would just ensure the tracking is only used if the page has completely loaded. If something has slowed down GA, it just won't bother trying to push the stats.

  3. Has anyone else found that _utf.gif never loads when opening external links with a _blank target?

    This happens with the default code Google provides, so not specific to this code. Google has provided instructions for a fix (, but I'm finding some folks for whom that doesn't work - the link just doesn't open at all.

    Bummer to spend so much time on something that seems to simple.

    I would use gsAddons, but can't stomach the $700 agency fee. There must be an easier way!

  4. Evan: make the calculation yourself "Bummer to spend so much time on something that seems to simple." Believe me, it's not "that" simple - and the code provided at will not work as is...

    I agree if you only wanted to track outbound links it $700 might seems a lot... But there are many other useful features (v2.1.2 released today!) and the price gives you the right to use gaAddons on any number of your clients (and I leave it up to you to figure out how you can make a profit by charging your added value as an analyst rather than as an implementation junky - the former being much more profitable!). How much time would you waste trying to develop and debug your own code? gaAddons now enjoys a big enough user base that the code is getting very robust.


  5. Howdy
    I just tried your script and it is exactly what I am looking for but I have a problem. I would like to use both of your examples. For example, if I want to be able to check for outgoing links in general on my site. Then I also want to check specific regions like "#footer a". These regions can have internal links but also external links. If I use your two scripts today as the link below it seems like the first script with external links get fired but not the one with with the "#main_menu a".

  6. on this page they recommend you put in a fraction of a second delay to ensure the click gets tracked, does your jquery version take care of that?

  7. Good peice of code.

    I have a question though. All of our links are hard coded on our Business Web Hosting site with the http (internal), and external links also have the http. So would the above code not see all links as outbound? which is not what we require...

    Whats the work around to this? We need to track external links but not at the sacrifice of losing tracking on our internal links or rearranging our existing linking structure..

  8. +1 for the previous comment from Business Web Hosting.

  9. I implemented the code above for a site I am tricking. It appears to know when all the right things are clicked however I dont see anywhere in Google Anaylitics where the document category is listed. Is there something that has to be set in GA for this to work?