Extend Google Analytics with jQuery
Originally posted on 16th May 2009 by Ian Harris
For quite some time now Google Analytics has been leading the way when it comes to gathering free statistics about the web traffic of your website. I’m sure that you many of you have installed the Google code on your sites and are already using the great reporting tools it provides. However, there are a few limitations to the standard service which you may or may not have come across yet. Using the standard code, we can only track views of pages where the tracking code is installed. It becomes a little bit more difficult if we want to track file downloads and external links, where we cannot add the Google JavaScript.
The aim of this tutorial is to show you how you can modify the standard Google tracking code using the power of jQuery to get extra information from your Google Analytics reports. With jQuery, we can get Google Analytics track your file downloads and clicks to external sites without having to trawl through your code and write any extra mark up.
We are also going to use a new feature of Google Analytics which are known as ‘Events’. This should give you a good base for you to build your own code and extend the power of Google Analytics even more.
Getting started
If you haven’t already, head over to the Google Analytics site and sign up for a free account. You will need to setup a Website Profile, which should be pretty self explanatory.
When you have your unique tracking code, either from your new Google account or from your current websites tracking code, take a note of the UA number, for example: UA-1234567-1. This is your unique identifier which tells Google what website to track and we will need it later on. If you already have the tracking code installed on your website, remove it now. Otherwise you could end up duplicating your stats!
Google Analytics Events
Before Google released the new pageTracker._trackEvent()
function, we would use the normal pageTracker._trackPageview()
function. To make your external links and file downloads stand out from your normal page visits, you can pass this function a modified url. For example, say we wanted to track the download of a PDF called myfile.pdf. We would add a pretend folder in front of the file name. This folder may not exist on your site, it’s there so you can easily spot downloads in your Google Analytics reports.
We could call this function like so:
1 | pageTracker._trackPageview('/downloads/myfile.pdf') |
You may wish to use this method instead of the newer functions, it’s up to you. However, I would recommend that you take a look into the new functions as it allows you to track much more.
For more information about tracking events read, the Google Analytics Event Tracker Guide. You will see how flexible the new method is and you can expand on this tutorial to track other events on your website.
Viewing you new events in Google Analytics
At present, the new event tracking function is still in beta on the Google Analytics site and not all accounts have access to view them by default. However, this is not a problem as you can add it in manually. When you are logged into your Analytics, type the following url into your browser: https://www.google.com/analytics/reporting/events. This will take you to events page. Once there, click on the “Add to Dashboard” button above the report and this will add the Events Tracking Overview section to your dashboard.
Integrating jQuery
There are a couple options available to you when you load the jQuery code; you can download a copy from the jQuery site and call it locally, or as we will do, call it directly from the Google code library. For more information why this is the better way to load jQuery, read 3 reasons why you should let Google host jQuery for you.
In the <head></head>
section of your HTML, copy and paste the following code.
1 | <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script> |
This load the minimised version of jQuery 1.3.2, which is the current verison at the time of writing, you may wish to check to see if there is a newer version available. For more information about jQuery, take a look at the jQuery Documentation.
Writing the custom tracking code
Still in the <head></head>
, directly beneath the code we have just inserted, enter the following:
1 2 3 4 5 6 7 8 9 10 11 12 | <script type="text/javascript"> $(document).ready(function(){ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); $.getScript(gaJsHost + "google-analytics.com/ga.js", function(){ try { var pageTracker = _gat._getTracker("UA-xxxxxxx-x"); pageTracker._trackPageview(); } catch(err) {} var filetypes = /\.(zip|exe|pdf|doc*|xls*|ppt*|mp3)$/i; |
Instead of loading the Google Javascript directly in the mark up, we are using the jQuery $(document).ready
function to load the code as soon as the DOM is ready, which means that our code is ready before any of the page content gets loaded. Therefore we can target elements, such as links, when they are loaded by the browser.
Next, we include the standard Google tracking code to register that the current page has been visited. The difference here is that we are using another jQuery function, $.getScript
, to load the Google JavaScript file and then create a function to run once the file is loaded. Make sure you replace the UA-xxxxxxx-x with your own unique UA number. We then set a variable called filetypes
which holds a regular expression to find any links with popular file extensions, you can add or remove any file extensions you wish.
Outbound links
Now we get to the part where we add the code which will actually start tracking the additional links. We will start with all of the external links on the page.
Add the following code to your script:
1 2 3 4 5 6 7 8 9 | $('a').each(function(){ var href = $(this).attr('href'); if ((href.match(/^https?\:/i)) && (!href.match(document.domain))){ $(this).click(function() { var extLink = href.replace(/^https?\:\/\//i, ''); pageTracker._trackEvent('External', 'Click', extLink); }); } |
The $('a').each
function will target each <a>
tag in turn and execute the code within the function itself against that tag. The first part of this function is to set a variable, href
, which will hold the value of the href
attribute of each <a>
tag.
Our first if
statement performs two checks. It is making use of the .match
function to check to see if the value of our href
variable either starts with http:
or https:
(using a simple regular expression) and that it does not contain the current domain of the website (i.e. it is external).
If this if
statement is returned true, we then add a click event to the current <a>
tag the our script is currently looking at. When this click event is triggered, we use another regular expression to strip the http://
or https://
from the link path. Finally, we use Google’s pageTracker._trackEvent
function to send the event details to our Google Analytics account. The first option for the function it to set the link category, I have used ‘External’. The next option is the to set the action, this has been set to ‘Click’. The last option is to sent the link label. This is set to the url of the external link.
Mailto: links
The next type of link we are going to target are any email address links that may be on the current page. As you know, the email address is preceeded with mailto:
, so we can easily pick them out with jQuery.
Directly after the last if
statement, add the following code to your script:
1 2 3 4 5 6 | else if (href.match(/^mailto\:/i)){ $(this).click(function() { var mailLink = href.replace(/^mailto\:/i, ''); pageTracker._trackEvent('Email', 'Click', mailLink); }); } |
This works in exactly the same way as the external link if
statement. We use a regular expression to find any email links, clean the link up by removing the preceeding mailto:
and then fire off the Google tracking event.
File downloads
The last type of links we are going to track are file downloads. Again, using a regular expression, we will check each link and match ita againsts the filetypes
variable we created earlier.
Add the following code to your script under the last statement:
1 2 3 4 5 6 7 8 9 10 11 | else if (href.match(filetypes)){ $(this).click(function() { var extension = (/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined; var filePath = href.replace(/^https?\:\/\/(www.)mydomain\.com\//i, ''); pageTracker._trackEvent('Download', 'Click - ' + extension, filePath); }); } }); }); }); </script> |
Again, the process is the same, but this time we are going to extract the file extension into a variable called extension
using yet another regular expression. If the link is an absolute link (i.e. it has the full http://www.mydomain.com/ in the file path), we removed the protocol and domain name as we don’t really need this in our Google Analytics reports as we already know that the link is local to our site. Make sure you replace mydomain.com
with your own domain name.
Here is the code in full (with the gaps removed so it fits on the page better):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <script type="text/javascript"> $(document).ready(function(){ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); $.getScript(gaJsHost + "google-analytics.com/ga.js", function(){ try { var pageTracker = _gat._getTracker("UA-xxxxxxx-x"); pageTracker._trackPageview(); } catch(err) {} var filetypes = /\.(zip|exe|pdf|doc*|xls*|ppt*|mp3)$/i; $('a').each(function(){ var href = $(this).attr('href'); if ((href.match(/^https?\:/i)) && (!href.match(document.domain))){ $(this).click(function() { var extLink = href.replace(/^https?\:\/\//i, ''); pageTracker._trackEvent('External', 'Click', extLink); }); } else if (href.match(/^mailto\:/i)){ $(this).click(function() { var mailLink = href.replace(/^mailto\:/i, ''); pageTracker._trackEvent('Email', 'Click', mailLink); }); } else if (href.match(filetypes)){ $(this).click(function() { var extension = (/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined; var filePath = href.replace(/^https?\:\/\/(www.)mydomain\.com\//i, ''); pageTracker._trackEvent('Download', 'Click - ' + extension, filePath); }); } }); }); }); </script> |
Conclusion
With the power of jQuery and the new Google ‘Events’, it is clear that you can take your website statistics further and produce more meaningful reports. This will help you gain a better understanding of how your website is being used and what your users and looking for, which can only be better for all concerned.
You can download the full code below, make sure you add in your own UA number and domain name.
extendga.js 1.62kb
Have you extended this code further? Have you found any other uses for the new Google ‘Events’? Perhaps you have written your own jQuery plugin with it. Please comment below and let us know, we would love to hear if you have found this useful in any way.
Thanks!
Resources
- jQuery
- jQuery Documentation
- Google Analytics
- Google Analytics Event Tracker Guide
- 3 reasons why you should let Google host jQuery for you
Comments
Comments are closed.
17th May 2009 at 1:38 pm
How can we track the time of users visit.
I think it will help in deciding maintenance period because you will know at what time you have least amount of visitors.
Thank You.
18th May 2009 at 1:33 pm
Hi Shishant,
I’m not aware of anything in Google Analytics that allows you to do this. However, you may be able to add a second
_trackEvent
function to each click event. Maybe you could set the catagory to Time and then use Javascript to dynamically set the Action/Label to the current hour of the day. That way you could track the busiest hours.Let me know how you get on.
Thanks!!
17th May 2009 at 9:35 pm
Very interesting article, and explained very clearly – I look forward to implementing this on my corporate website.
Already looking forward to the next CM article!
Thanks
Stuart
18th May 2009 at 12:17 pm
Very interesting and great article indeed.
Looking forward to try it as well!
Thanks for sharing
18th May 2009 at 3:11 pm
I wrote a jQuery plugin that incorporates this functionality against the old urchintracker version of GA back in 2007. The original post is here:
http://devblog.jasonhuck.com/2007/11/19/google-analytics-integration-with-jquery/
Since then, David Simpson has quite nicely expanded on that code and updated it to work with the current ga.js script. He’s done a great job with it. The current version (about a year old now) is here:
http://davidsimpson.me/2008/06/18/jgoogleanalytics-google-analytics-integration-for-jquery/
We use this on our sites now and it works great.
– jason
18th May 2009 at 7:37 pm
Great article with good tips on extending the capabilities of the standard app.
Shishant – You can track visits per hour by clicking on Visits from the Site Usage dashboard. Below the date bar, you’ll see graphing options. Click on the option that looks like a clock. You’ll then see visits by hour.
19th May 2009 at 7:24 am
The events of analytics are very interesting. If to this we join the jquery the results are spectacular.
Thanks
19th May 2009 at 10:35 pm
Thanks for a decent article. I’m looking forward to read it thoroughly and give it a try.
Thanks
12th June 2009 at 10:57 am
Hi there.
Great article. I’m gonna take a look at it and see if we can implement it.
Thank you!
10th August 2009 at 8:04 pm
Must say this is one of the most interesting articles I’ve read in a while. I’ll definately be giving this a try.
Thanks for sharing.
17th August 2009 at 10:24 am
This was a very well written tutorial. We are testing this code now.
Thank you for posting.
17th August 2009 at 10:37 am
Hi. Great post. Thanks!
Newbie question:
We are running some in-text advertising js code that is also supposed to be placed before the ending html tag.
Can we include this ja in your $(document).ready(function(){} code, for example, here?
blah blah blah code
});
Or, should we do it differently?
17th August 2009 at 10:51 am
Hi Tim,
Yes, you should be able to use the same method, but the only way to tell is to give it a go. Some scripts may not like it, but I haven’t had one yet.
Thanks for the comments, I’m glad this has been useful for you.
Ian
17th August 2009 at 11:55 am
Hi Ian,
BTW, We get an error in the error console when we run the code in this post. We tried it “full code” and also tried it “outbound clicks only”, but got the same error.
I forwarded you a screen dump, because I could not cut-and-paste from the Opera error console.
Cheers.
17th August 2009 at 12:35 pm
Hi Neo,
I’ve sent you an email. I looks like there is a conflict with jQuery.
Try replacing all of the ‘$’ symbols in the script with ‘jQuery’. This should help prevent any conflicts. For example, “$(‘a’).each(function(){” would become “jQuery(‘a’).each(function(){“.
Hope this helps!
Ian
17th August 2009 at 6:03 pm
Hi Ian,
Thanks! I wish I knew jQuery like you.
I’ll post back the results of implementing your suggested changes, when I get a low traffic window to implement and test.
Cheers.
4th September 2009 at 12:33 pm
Jquery.getScript() does NOT cache!
So if you follow the instructions in the custom tracking script section you will now be downloading ga.js for each request instead of hitting the browser cache.
http://jamazon.co.uk/web/2008/07/21/jquerygetscript-does-not-cache/
25th September 2009 at 10:50 am
Is there a way to get the full file path of a link if it is relative path for example:
Current page http://www.yourdomain.com/hr/subsection/document.html
Link
../downloads/document.doc
So the final path would be
http://www.yourdomain.com/hr/downloads/document.doc
12th November 2009 at 7:42 pm
Hi,
What if I want to host the extendga.js file in a subdomain instead of the actual domain for example in sub.domain.com/extendga.js ? Should the code be modified to enable this fox example:
try {
var pageTracker = _gat._getTracker(“UA-xxxxxxx-x”);
pageTracker._setDomainName(“.domain.com”);
pageTracker._trackPageview();
}
catch(err) {}
http://www.google.com/support/googleanalytics/bin/answer.py?hl=en&answer=55524
Thanks!
12th November 2009 at 10:36 pm
Hi,
It doesn’t matter where the extendga.js JavaScript file is called from as the code is effectively inserted into the page itself. You could host the file on a completely different domain if you wish, however it’s probably not recommended due to latency issues.
Therefore you will not need to modify the code if you host it in your sub domain. As it happens, we host the file on a sub domain of this site.
Hope this helps,
Ian
26th January 2010 at 4:42 pm
Hi !
Many thanks for the great article.
I’m looking for a way to track external accesses to my PDF’s URLs, I mean when someone browses directly for the URL without loading any web page where the onClick event is located.
Is it possible? Any hints?
Many thanks !!!!!
12th March 2010 at 4:00 pm
Hi Ian, I just thought I’d chime in on an error that I noticed. Any old-school anchors with the name attribute used to send a user to navigate to a different location within the page that do not include an HREF attribute will throw an error. It’s an easy fix:
$(‘a[href]’).each(function(){
Cheers!
14th April 2010 at 9:27 am
When I use your script, I get an error in Firebug:
href is undefined
[Break on this error] if ((href.match(/^https?:/i)) && (!href.match(document.domain))){
Line 21
I use jQuery 1.4.2
How can I solve this?
14th April 2010 at 10:43 am
Hi Johan,
I think that Brendon has posted a fix for this in the comments already. Find the line
$('a').each(function(){
in the file and replace it with$('a[href]').each(function(){
. This filters out any<a>
tags that do not have anhref
attribute.Thanks to Brendon for pointing that out, I will update the post later with this fix.
Cheers,
Ian
14th May 2010 at 1:02 am
Thanks for this great article Ian. Really well written and easy to follow.
Is there a way to also see which page the links were clicked on in your site?
5th August 2010 at 12:54 pm
Hi Ian, does this mean we won’t need the normal GA code since this already includes it?
Thanks for a great article!
Len
5th August 2010 at 2:38 pm
Hi Len,
Thanks for the comments! Yes thats right, you no longer need to include the Google code at the bottom of the page.
Thanks again,
Ian
16th October 2010 at 1:02 pm
I have installed your tracking code and it is working partially. It is tracking clicks on links to external sites but not tracking clicks to download a document on the page
How can I track this event with your code?
/>
I would like to see how many clicks or “Plays” each file gets like LoveSong for media/LoveSong.mp3
Thank you for your advice.
Hal
2nd December 2010 at 9:30 pm
Ian, I was trying to simplify the process as best I could and have been having problems doing so. Since you’ve worked with GA’s Event Tracking…can you see any reason why this code wouldn’t work?
http://pastebin.com/VyB1aijn
2nd December 2010 at 11:56 pm
Hi Brendon, try changing line 16 to :
$('a[href^="http"]').not('a[href*="'+domain+'"])').each(function(){
I haven’t tested this, but let me know how you get on.
Thanks,
Ian
3rd December 2010 at 4:22 pm
Hey Ian, thanks for taking a quick look. The problem seems to specifically be that the event tracking itself is not working. I’ve checked the hyperlink onclick event with a simple alert box and that seems to work as expected. If I simply run a call to trackPageview instead of trackEvent, the call works.
I’ll try your code anyway since I’m picking at straws. 🙂 Thanks!
9th December 2010 at 7:44 pm
The problem was that I wanted to track where the page from which the current click came from, so I used:
document.location
Unfortunately, this is not strictly a type of “String” in JavaScript (and google’s methods for analytics are strictly typed). It’s an object with properties. One could have assigned it to a variable and then used toString(), or just used the property .href on the object to get the desired string to pass to the trackEvent method. Once I (finally realized and) did that, all was happy in Google Analytics land. Thanks again for taking a quick look over it! I never thought document.location was not of type “String” since alerting it will show (by default) the value of document.location.href. Oops.
9th December 2010 at 8:46 pm
I wrote about doing something similar, but with the new Asynchronous Tracking Code. I don’t go into as much detail as you do, but people may find it helpful:
http://stephenakins.blogspot.com/2010/12/link-tracking-using-jquery-and-google.html
28th January 2011 at 10:43 pm
Thanks for the great tutorial, well explained and easy to implement!
My question I think is pretty basic…
Instead of pulling the href with the full link name, is it possible to pull a different user-defined variable associated with the link, such as the title attribute or some other user-definable variable? So extLink would be something like extTitle, making it a more user-friendly name?
Thanks again!
Ethan
28th January 2011 at 10:44 pm
Correct email address.
28th January 2011 at 10:49 pm
Is it possible not to exclude own domain? Would it look like this?
//check for links starting with http or https, making sure that links to our own domain are excluded
if (href.match(/^https?:/i)){
$(this).click(function() {
var extLink = href.replace(/^https?:///i, ”);
pageTracker._trackEvent(‘External’, ‘Click’, extLink);
});
29th January 2011 at 12:13 pm
Hi Ethan,
Yes, that should work, although I’m not sure why you would want to do this as each time one of your internal links is clicked, it will then be recorded twice in Google Analytics.
Many thanks,
Ian
29th January 2011 at 12:11 pm
Hi Ethan,
Many thanks for the nice comments!
Yeah, you can pull what ever information you like from the link. First of all, you’ll need to cache the
$(this)
object in a variable, then you can select which attribute to choose. The final code could look like the following:$('a').each(function(){
var curLink = $(this);
var href = curLink.attr('href');
if ((href.match(/^https?:/i)) && (!href.match(document.domain))){
curLink.click(function() {
var extLink = curLink.attr('title');
pageTracker._trackEvent('External', 'Click', extLink);
});
}
I haven’t tested this, so please let me know if it works OK.
Many thanks,
Ian
6th May 2011 at 8:50 pm
Hi,
Very good post, I translated it in French on this page: http://blog.carnould.com/2011/05/comment-ajouter-des-evenements-google-analytics-avec-jquery/
And I put a trackback to your website.
9th May 2011 at 8:59 am
Hi Cédric,
Thank you very much! (Merci beaucoup!)
Ian
20th June 2011 at 9:05 am
Hi Mike,
Let me know if you need a hand, drop me an email when you are ready.
Speak to you soon,
Ian
24th October 2011 at 10:38 am
Hi Ian,
I found a slight issue in the script if the page contains anchor tags with no hrefs (eg when used with an id for in page links). The lines “href.match” were throwing “href undefined” errors for those links. I didn’t try to see if this prevented the script as a whole from working, but I thought you might like to know. I solved this by wrapping the href.match statements in
if(!(typeof href === “undefined”)) {
}
Thanks for the excellent script though.
Regards,
Robin
9th November 2011 at 5:16 pm
I know very little about jQuery, but I’m trying to implement this on an older website whose download links tend to look something like this: http://ccrc.tc.columbia.edu/DefaultFiles/SendFileToPublic.asp?ft=pdf&FilePath=c:Websitesccrc_tc_columbia_edu_documents332_974.pdf&fid=332_974&aid=47&RID=974&pf=Publication.asp?UID=974
Do you think this script should be able to pick out the file type from all that so I can track downloads?
Unfortunately, I can only upload files through a content management system that generates download links like that, so I can’t make them any cleaner.
16th December 2011 at 3:52 pm
Hi,
Thanks for the article. I am trying to implement on website powered by CommonSpot CMS, but it is showing all the JS code on the pages.
Did I missed anything?
Thanks,
Ashraf
30th January 2012 at 6:01 pm
Thanks for this great info..!
Is it applicable to asynchronous tracking code?
16th February 2012 at 1:25 pm
var href = this.href;
is much faster than
var href = $(this).attr(‘href’);
No need to use jQuery.
1st May 2014 at 5:52 pm
Can you add a Blackberry template? This web page is tricky to read otherwise for those of us browsing with cell phones. Otherwise, in the event you can place a RSS link up, that would be good also. dbgadadagdce
28th May 2015 at 9:48 am
Hi. Any updates to the code since first posted or an additional PHP library with examples for us to follow?
Thanks