Making All Internal Link Clicks a Conversion

A common use case of Google Website Optimizer (GWO) is to test (in order to optimize) a page's ability to have a user click an internal link, I like to call this the internal pass thru rate of a page. Meaning the click event of any internal link on a test page will count as a conversion for the test. This is not the opposite of the bounce rate which it is sometimes mistaken for, because the pass thru rate is oblivious to the difference between first time visits and other visits. The pass thru rate is not the same as the click thru rate either, because the pass thru rate relates to visits and the click thru rate relates to impressions. This is usually desired either because you have no other conversion to track -- although time on page is always another option, but the results typically take longer to acquire -- or because you wish to optimize the bounce rate, and this is as close as you can get at the moment.

Google doesn't have any documentation on how to track all internal links on a page, but they do provide a page on how to track an individual link, which any novice JavaScript programmer can follow in order to track all of the internal links, by simply repeating the process for every internal link on the test page(s). The main problem here is that Google's process requires that the onclick attribute of every link be set to "return false", albeit this can be done via JavaScript, it is not desirable. Google Website Optimizer's Technical Lead Engineer, Eric Vasilik, explained Google's method in a blog post from August 2009, called "Tracking Outbound Links -- The Right Way", and I wrote a follow up post in December 2009, called "Tracking Outbound Links - The Really Right Way" in which I describe a better method which is slightly harder to implement but does not require any use of the onclick attribute.

If you are at least a novice JavaScript programmer that wants to measure the pass thru rate of a page, then you can probably implement Google's method or mine with relative ease after reading the blog posts I mentioned.

If you are not a novice JavaScript programmer, or simply want to save some time implementing this type of conversion over and over again, then I would suggest you take a look at the JavaScript click track library that I released in early December '09, because with this javascript library you could simply add the following code to your page:

clickTrackingLib.addMatches([{
match: clickTrackingLib.getMatchPreset( "all-internal" ),
trackingFunc: function(e, link){
var gwoTracker=_gat._getTracker("UA-XXXXXXX-X");
gwoTracker._trackPageview("/YYYYYYYYYY/goal");
}
}]);
clickTrackingLib.attachTrackingFunctions(null,99);

The above code will tag all non-rel-external links or links with the internal hostname on the page; for just internal hostname links replace "all-internal" with "internal-hostname". I would recommend that you wrap the above into a function though, to be run on the DOM ready event or page loaded event, with jQuery that would look like:

$(document).ready(function(){
clickTrackingLib.addMatches([{
match: clickTrackingLib.getMatchPreset( "all-internal" ),
trackingFunc: function(e, link){
var gwoTracker=_gat._getTracker("UA-XXXXXXX-X");
gwoTracker._trackPageview("/YYYYYYYYYY/goal");
}
}]);
clickTrackingLib.attachTrackingFunctions(null,99);
});

The first line in the code above will setup a function to be executed when the DOM is ready, and all of the page's links have been added. The second line is the first of the function the be executed on DOM ready, and it is adding an array of match objects to the global clickTrackingLib object provided by the click tracking library that I wrote. The following 5 lines define a single match object for the input array, which consists of a preset match function to match internal links (as I said already this preset can be changed, and you can also define a custom match function), and a simple tracking function. When clickTrackingLib.attachTrackingFunctions(null,99); is executed, links are tested against the match functions in the clickTrackingLib object's match object array, and where there is a match the associated trackingFunc function is made in to a onclick event listener for the matched link. As for the two inputs, the null means try all links, and the 99 means use a 99 millisecond delay.

At this point you might be wondering, what if the page has dynamic content, which is changed via ajax, well in that case you can round up the new link(s) in to an array and run the clickTrackingLib.attachTrackingFunctions(links, delay) function again like so:

clickTrackingLib.attachTrackingFunctions(newLinksArray,99);

clickTrackingLib.attachTrackingFunctions(links, delay) will also accept a single link.

Tracking Outbound Links - The Really Right Way

About 5 months ago Eric Vasilik wrote a post on his GWO Tricks blog about Tracking Outbound Links -- The Right Way which was ment to point out a solution for the problem with the technique outlined in the Analytics Help Center article called "How do I manually track clicks on outbound links?", is that it suffers from a Race Condition which may mean the tracking doesn't take place. If you haven't read Eric's article, please do.

Well as readers of my blog would know, I recently wrote a JavaScript click tracking library which can be found at GitHub here. In the blog post I mention that I implemented Eric Vasilik's "Right Way" to track links, but today I started thinking about this some more.

I decided to do some searching on how to cancel a click event, and I found a great old blog post from 2006 by Ryan Campbell pretty quickly which mentions a method implemented by Prototype called Event.stop(). So I decided to dig in to the Prototype code to see what Event.stop() did exactly, so I could extract it, and I found that it does two things, one is to stop the event propagation, and the second is to stop the default behavior for the event. At the end of the post Ryan said that it not work for Safari 2.0.3, which is why it could not be relied on at the time, but today Safari 2.0.3 is dead, and I tested Safari 3 out which works. In fact I decided to do some PPK style testing and try test cases on every browser I could.

After seeing that Event.stop() had two purposes I wanted to find out why this was done, and found this documentation page for Event.stop(), which says this was done "because stopping one of those aspects means, in 99.9% of the cases, preventing the other one as well", but in the case of simply click tracking we don't really want to stop the event propagation, we just want to stop the default action from being triggered eventually. So here is what my update to Eric's example looks like:

<a id="example" href="http://www.example.com">Click me</a>
<script type="text/javascript">
function doGoal(e){
if(!e) var e = window.event;

var targ;
if ( e.target ) targ = e.target;
else if ( e.srcElement ) targ = e.srcElement;
// Safari..
if ( targ.nodeType == 3 ) targ = targ.parentNode;

setTimeout('document.location = "' + targ .href + '"', 100);

try{
var pageTracker=_gat._getTracker("UA-123456-1");
pageTracker._trackPageview("http://www.example.com");
}
catch(err){}

if (e.preventDefault) e.preventDefault(); // w3c
else e.returnValue = false; // for ie
}
if ( document.body.addEventListener ) {
// w3c
document.getElementById('example').addEventListener( "click", doGoal, false );
}
else if ( document.body.attachEvent ) {
// ie
document.getElementById('example').attachEvent( "onclick", doGoal );
}
</script>

To try the code above see the test page here. I have tested this out on IE6+, FF2+, Opera9+, Safari for the iPhone OS 3.0, Google Chrome, and Safari3+ on MacOSX and WindowsXP and they all work, so I am pretty confident that this is going to work for something like ~99% of web users today, and since it would not error even for a user using Safari 2 (which I wasn't able to test), and Safari 2 is so slow, there is a good chance the user would still be tracked anyhow.

If anyone else could try this out on some other browsers at let me know what they find good or bad that would be nice so that I can add them to the list above. The best way to test the test page is to comment out the setTimeout line, and make sure that clicking the link doesn't do anything.

The beautiful part about this method is that it is totally unobtrusive JavaScript code, and will work even if you are using the onclick attribute for other site functionality (even though you shouldn't ever use the onclick attribute).

Merry Clicking!

P.S. The Click Tracking JavaScript Library has been updated to use this really right method, check it out if you haven't already!

Click Tracking JavaScript Library Now Available

Purpose

To help web publishers easily track link clicks the correct way, across browser platforms, with tools like Google Analytics (GA) and Google Website Optimizer (GWO).

Typically a web publisher will want to do something like track all external links on a website with GA, setup a GWO test where the conversion is a click through, or do both on the same page for a few pages of their site. This javascript library was designed to make tasks such as these simple.

About

clickTrackingLib

Adding the click-tracking-lib.js or the click-tracking-lib-with-presets.js to a web page provides you with a clickTrackingLib javascript object. Once you provide clickTrackingLib with some match objects, you can then have clickTrackingLib scan a single, set, or all document links to determine if the link(s) should have tracking functions applied to it or not, and do so if needed. If one or more tracking functions are applied to a link, then a delay function will be applied to the link (this can be disabled too of course, and the delay can user defined but the default is 99 ms).

The Delay Function

The delay function is meant to delay the user from being redirected to a new page for just a bit to allow time for say a Google Analytics image request to complete, and avoid being canceled by the user's browser. It can be disabled, but it is added by with a 99 sec delay by default, which can be customized, as the very last onClick event listener, after all of the desired provided Match object trackingFunc's are applied.

The delay function technically only sets a timeout to redirect the user after x ms, but in order for the delay to work the link's default functionality, namely redirecting the user, needs to be disabled, if the link doesn't just open in a new tab (target="_blank" and target="_new" are checked for). To disable the default functionality the link's onclick attribute must be set to onclick="return false;" which I figured should be fine because all well made websites won't use that attribute except to make it equal to "return false;" anyhow. If your site is not well made, then you should think about fixing it or having it fixed for you, but you can still use this library by simply not using the delay function and implementing it by some other means.

Presets

There are a number of presets available if you use click-tracking-lib-with-presets.js or click-tracking-presets.js; presets are predefined match functions for common use cases, such as matching all internal links, or external links, or download links. They can be used as they written, you could cut out the ones you won't use, or simply use them as examples when you define your own custom match objects.

The can be accessed from the clickTrackingLib.getMatchPreset( name ) method. The possible name values and the meanings behind them are as follows:

  • 'rel-external': matches rel-external links
  • 'external-hostname': matches external hostname links
  • 'all-external': matches all rel-external and external hostname links
  • 'filetypes': matches file names: (docx*|xlsx*|pptx*|exe|zip|pdf|xpi|rar|xls)
  • 'non-rel-external': matches non-rel-external links
  • 'internal-hostname': matches internal hostname links
  • 'all-internal': matches non-rel-external links or internal hostname links

Match Objects

Any object that has a 'match(link):boolean' method and 'trackingFunc(event,link):void' method defined.

match(link):boolean

This method will take a link element as input, run some test on it and return true or false, if true is returned then the Match object's trackingFunc will be added to the link.

trackingFunc(event,link):void

This method will be provided with two input values; event is the click event object, and link is a reference to the link element. You can obtain a reference to this from the event object, but there is some cross browser logic you would need to implement, so I thought a direct reference to the link would be handy. The function should not return anything.

new clickTrackingLib._clickTrackingLib();

If you want to create multiple clickTrackingLib objects, that contain different sets of match object arrays, then you need to create a new one, like so:

var myNewClickTrackingObj = new clickTrackingLib._clickTrackingLib();

This will give you a new object, myNewClickTrackingObj, which is like clickTrackingLib in all but two ways. First myNewClickTrackingObj will not have a _clickTrackingLib() method, and second it will not have a getMatchPreset() method, even if clickTrackingLib.getMatchPreset() was defined. This is because you don't need a bunch of objects in memory with those two methods, only one, which is the singleton clickTrackingLib object.

How To Use

  1. Download either click-tracking-lib-with-presets.js or click-tracking-lib.js (see ABOUT fore more information) from the project repository at GitHub.
  2. Minify it with one of the following options:
  3. Upload the minified script to your site.
  4. Add <script src=".." type="text/javascript"></script> for the script to the desired pages.
  5. Write some code:
    • define some match objects (just an object with a match method and trackingFunc method)
    • Add match objects to your clickTrackingLib object
    • Call the clickTrackingLib.attachTrackingFunctions( links, delay ) when desired.
      • links: can be a single anchor element, an array of anchor elements, or falsely so that the default is used, which is document.links.
      • delay: should be a positive integer or falsey, in the latter case no delay function will be added to the links scanned, in the former case a delay function will be applied with the specified delay value.

[More]

Start Tracking Your JavaScript Disabled Visitors With GA.CFC

Google Analytics depends on JavaScript to make image requests to GA servers, and therefore only tracks your JavaScript enabled visitors. This is why Remy Sharp wrote a blog post a few weeks ago called "The Missing Stat: noscript" where he outlined some work he'd done on how to track your noscript visitors with Google Analytics and PHP.

If you read the comments on Remy's post, you will see that his PHP code was ported to .NET by Erik Zaadi which is available at Github here and called "GA.NET". Erik also wrote about his project here.

So after reading all of this I decided to port the code to ColdFusion, but after reviewing the code Remy wrote I started to see some real potential for handing the GA tracking logic for the image requests made to GA servers with server side code. In other words, you should be able to track page views, events, and more on your visitors that have JavaScript disabled.

So I started GA.CFC for ColdFusion and put it on GitHub, it's basically Remy's PHP code ported to CF, with the one difference being that when using GA.CFC you must provide the domain hash which GA generates to GA.CFC, which I guess Remy thought was a random number; his code worked anyhow apparently though.

I plan to extract GA's hash function later so that you won't have to input the domain hash, and I have plenty more updates planned for the future, but I decided to upload GA.CFC to GitHub now so that others can use it in the meantime.

Currently you can track pageviews, but each page view is considered a new visitor. Please read the README file for GA.CFC for usage instructions.

Get GA.CFC at GitHub here

The Daily UserScript: Google Analytics Referring Source Detail Links

This userscript will make the referring source on the source detail reports of Google Analytics into a link.

The Unpleasantry:

The referring source is displayed at the top of the source detail reports pages, namely the 'Referring Site' and 'Referring Link' reports, but this is not a link, which I commonly wish it were.

The Alleviation:

Once you install the "Google Analytics Referring Source Detail Links" UserScript the referring source will be made in to a link that will open the referring source in a new tab.

[More]

You Can Finally Prove Your GAIQ Score!

Since Google launched the Google Analytics Individual Qualification (IQ) program nearly 8 months ago, a lot of people have asked for (I was one of them):

  1. A way to prove to others that they have passed the Google Analytics IQ test and what their score was.
  2. A badge that qualified GA individuals can put on their personal and/or company website.

Issue I: We wanted proof!

Well Google finally got around to addressing the first issue today enabling those that passed the GAIQ test to create a link to proof that they passed, for example here is my proof of passing the Google Analytics IQ test.

I really must thank Google for finally addressing this, it finally means people that are looking for someone to help them with Google Analytics will have a metric that they can use to wade through all of the people out there that either did not pass the test and claim to, or did not do very well. Of course an educated decision will depend on far more than a test score, but it is very important nevertheless.

Issue II: We wanted a badge!

Early last month I got a wicked email from Kamal:

Hi Erik,

I came across your site through a search on a google analytics related query and I noticed that you're a GAIQ. Would you like to be listed in the GAIQ Directory at http://www.GAIQDirectory.com? There's a submission page at http://www.gaiqdirectory.com/submit-your-gaiq-listing and a set of badges at http://www.gaiqdirectory.com/badges

...

Thanks,
Kamal

So I decided to check out this unoffical GAIQ Directory and submitted my listing, which you can see here, and I was pretty pleased with the site, but very pleased with the badge you can see in this post. Why Google never made this I do not know, but a lot of what they do is highly questionable, Hanlon's razor must apply here.

The Unoffical GAIQ Directory has barely been used, there appear to be 6 people in the directory currently, so if you have passed the GAIQ test, then I highly recommend submitting your listing there. Hopefully they will display score results soon hint hint.

The Daily UserScript: Insights For Analytics

Today's userscript is one I worked on with seOverflow a couple of weeks ago which was released today. The Insights For Analytics UserScript is a new free tool from seOverflow which adds Google Insights widget to Google Analytics. This new widget makes analyzing keywords that bring real traffic to your site extremely easy!

Watch for a Better Google Analytics update soon to include this userscript and more new features very soon!

The Unpleasantry:

Currently when you want to view keyword trends for keywords in your Google Analytics reports you have to manually open a tab to either Google Insights or a similar tool, paste the keywords, and customize the date before finally hitting submit.

The Alleviation:

Once you install the "Insights For Analytics" UserScript you have a better option, which is to use the new Google Insights widget available to you on every Google Analytics keyword report.

Features

  • Check up to 5 keywords in keyword reports with checkboxes, and click search to open a new tab with a Google Insights search ont he checked keywords.
  • The date range is automatically fit to match the Google Analytics date range you had set.

Screen Shot

The Quotidian UserScript: Google Analytics Row Limit Link

I was reading a post made yesterday on the Google Analytics Blog by Christina Park (a Google employee), titled "Back to Basics: Tip for exporting rows" and a userscript came to mind to improve this process a great deal.

The Unpleasantry:

If you want to export a report from Google Analytics with every row displayed, then if you follow the instructions laid out for you by Christina you would:

  1. Go to the bottom of the report and find the pagination details.
  2. Append "&limit=x" to the url in the location bar, where x is the number of total number rows in the report which you obtained by reviewing the pagination details.
  3. Hit enter, to load the modified url.
  4. Export as normal.

But wait, there is a problem.. if you changed the date while you reviewed the report, or made some other change to the report after it loaded initally, then those changes won't be reflected in the url which you will append "&limit=x" to. This means that the page that loads after you have appended "&limit=x" will be without the changes you made.

One way to get around this currently is to use the navigation to change to another report, which will keep the same date range, comparison range, segments selected, and other changes you made, then flip back to the report you were just on, and then finally append "&limit=x" and do the export. But this is all very tedious.

The Alleviation:

Once you install the "Google Analytics Row Limit Link" UserScript the total row count in the pagination details at the bottom of each report will be a link, simply click it and the total number of rows will be displayed in the report (note: your start row is unchanged). This is not only much simpler then the help that the Google Analytics team provides, but it also saves their servers from tons of redundant page loads.

The Daily UserScript: Google Analytics URL Builder Override Option

Today's userscript addresses a HUGE USABILITY FAIL by the part of Google Analytics team that oversaw and built the Google Analytics Tool: URL Builder. The issue I refer to is the flout of the utm_nooverride url variable.

The Unpleasantry:

Take a look at the current process to add the utm_nooverride url variable:

  1. You're fucked, paste it in yourself! if you remember how to use it properly, and if you can't remember then good luck finding real documentation haha!.

The Alleviation:

Once you install the "Google Analytics URL Builder Override Option" UserScript the "Campaign Override" option will be part of the URL Builder form along with help information and a link to official reading on the utm_nooverride campaign url variable; as it should have been to begin with..

The Daily UserScript: Add Profile Settings Link to Google Analytics

Sometime last year Epik One came out with a simple userscript for Google Analytics (GA) adding a 'Profile Settings' link (here is the link). I always liked the idea for this userscript, and I even included it in a blog post I wrote on October 20th 2008: Greasemonkey Scripts That Make Google Analytics Better! where I mention that it disables the cleanerGAProfileSwitching. This conflict is due to the poor javascript work in Epik One's userscript, not mine, specifically their use of innerHTML. In fact their use of innerHTML also prevents the profile drop down menu from working. This type of programming is why I wrote a blog post explaining how to avoid the use of innerHTML in your JavaScript code.

The userscript was a great idea, but a very poorly executed one. However, when I created the Better Google Analytics Firefox Extension I wanted to include their idea, and emailed them asking permission to do this, but never got a response from them. Had I gotten a response I probably would have helped them with fixing their userscript, but being ignored is rather annoying, so I decided to just completely rewrite their idea as a new userscript.

The Unpleasantry:

Take a look at the current process to edit the profile settings of the Google Analytics profile which you are viewing reports for:

  1. Click the 'Analytics Settings' link.
  2. Click on the desired account.
  3. Find the desired profile, and click the associated edit link.

The Alleviation:

Once you install the "Add Profile Settings Link to Google Analytics" UserScript you have a better option, which is:

  1. Click the 'Profile Settings' link.

Screen Shot:

This screen shot shows the 'Profile Settings' link to the right of the 'Analytics Settings' link.

More Entries

© Erik Vold 2007-2010. Contact Erik Vold. Top ^