Track Outbound Links – Google Analytics

Goal: Use JS to automatically track outbound links that do not have a target=”_blank” attribute – in a dynamic and informative way.

Earlier in the week I was tasked with implementing Google’s Analytics system onto a fleet of websites that have different hostnames. This created many outbound links that weren’t tracked because they lacked a target=”_blank” attribute. This is a solution for websites using tools such as WordPress – and a plugin will be available eventually.  I’ve created a small snippet of Javascript/JQuery to run through a page, checking for external links – and modifying them to be tracked by Google’s servers with an onClick event. In using jQuery to solve this problem, you need to ensure you load jQuery into your page before running any of my script.

Step 1: Google’s Launch Pad – trackOutboundLink

Google has provided a function for converting a given URL into an event name for use in Analytics found here : https://support.google.com/analytics/answer/1136920?hl=en. This is standard Javascript and does not need to live within a jQuery wrapper. This function needs to be placed in the head of the document and not restricted in it’s runtime by a jQuery document.load() call.

<script type="text/javascript">// <![CDATA[
/*
* Function that tracks a click on an outbound link in Google Analytics.
* This function takes a valid URL string as an argument, and uses that URL string
* as the event label.
*/
var trackOutboundLink = function(url) {
   ga('send', 'event', 'outbound', 'click', url, {'hitCallback':
     function () {
     document.location = url;
     }
   });
}
// ]]></script>

Step 2: Checking URL Against the Hostname

Below we create a new function for comparing if a hostname is within a URL. The function takes ‘a’ and ‘b’ as variables, if unset return false, otherwise return the index position of our ‘b’ variable and check if it’s greater than or equal to index position 0. Greater than 0 means the string was found in our tested URL and will return true. Returning true implies the URL is internal, and can be left as is.

	function urlInternal(a, b) {
			if (!a || !b) {
				return false;
			} else {
			    return a.indexOf(b)&gt;= 0;
			};
	};

Step 3: Checking and Appending Anchors

For each anchor tag on the page, we get the href attribute and run it through our urlInternal function. Note the ! before my function call, if this weren’t here we would be evaluating all of the true statements where we want false (URL is NOT internal) results only. If the URL is external, using Google’s function and some concatenation – we write the new onclick attribute.

	var $hostBaseUrl = window.location.hostname;

	jQuery('a').each(function() {
			var $this = jQuery(this);
			var $url = $this.attr('href'); 

			//console.log($url,$hostBaseUrl,$linkBaseUrl);

			if(!urlInternal($url,$hostBaseUrl)){
				var $linkBaseUrl = $this.prop('hostname');
				var	$linkBaseLocation = "trackOutboundLink('http://" + $linkBaseUrl + "'); return false;";
				$this.attr('onclick',$linkBaseLocation);
				return;
			}
		});

Summary

Somewhere in the head of your page (that you want to change the link onClick of) include this function that we can call each time we find an external link.

	/**
	* Function that tracks a click on an outbound link in Google Analytics.
	* This function takes a valid URL string as an argument, and uses that URL string
	* as the event label.
	*/

	var trackOutboundLink = function(url) {
	   ga('send', 'event', 'outbound', 'click', url, {'hitCallback':
	     function () {
	     document.location = url;
	     }
	   });
	}

Run this script before the function and you should be good to go.

jQuery(document).ready(function(){

	/**$hostBaseUrl saves the current URL's hostname for later use. Eg: on google.ca/happy/two.pdf -&gt; google.ca is our hostname **/
	var $hostBaseUrl = window.location.hostname;

	/**Check if a, b are set variables and then check if b occurs in a - returns true or false because of &gt;= 0**/
	function urlInternal(a, b) {

			if (!a || !b) {
				return false;
			} else {
			    return a.indexOf(b) &gt;= 0;
			};

	};

	/**Scan through all anchor tags on the page and get their href attribute**/
	jQuery('a').each(function() {
			var $this = jQuery(this);
			var $url = $this.attr('href'); 

			/**If the link is NOT internal, get it's hostname and call Google's function to write the onclick attribute**/
			if(!urlInternal($url,$hostBaseUrl)){
				var $linkBaseUrl = $this.prop('hostname');
				var $linkBaseLocation = "trackOutboundLink('http://" + $linkBaseUrl + "'); return false;";
				$this.attr('onclick',$linkBaseLocation);
				return;
			}
	});
});

Leave a Reply

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