Track all outbound links in Google Analytics

13,182

Solution 1

The reason for the :80 in your output is because of e.currentTarget.host

http://www.w3schools.com/jsref/prop_area_host.asp

I'm not sure why you are tracking that in addition to your already functional url variable, but you can always insure that :80 is not there with a simple string replace

_gat._getTrackerByName()._trackEvent("Outbound Links", e.currentTarget.host.replace(':80',''), url, 0);

Solution 2

Fresheyeball answer is the correct one, but because many people have been asking for a complete answer, I'm going to post the final script with Fresheyeball's contribution.

The short version

// Outbound Link Tracking with Google Analytics
// Wallace Sidhrée - http://dreamyguy.com/
// Requires jQuery 1.7 or higher (use .live if using a lower version)
$(function() {
    $("a").on('click',function(e){
        var url = $(this).attr("href");
        if (e.currentTarget.host != window.location.host) {
            _gat._getTrackerByName()._trackEvent("Outbound Links", e.currentTarget.host.replace(':80',''), url, 0);
            if (e.metaKey || e.ctrlKey || this.target == "_blank") {
                var newtab = true;
            }
            if (!newtab) {
                e.preventDefault();
                setTimeout('document.location = "' + url + '"', 100);
            }
        }
    });
});

The complete version (commented and 'debug-able')

// Outbound Link Tracking with Google Analytics
// Wallace Sidhrée - http://dreamyguy.com/
// Requires jQuery 1.7 or higher (use .live if using a lower version)
$(function() {
    $("a").on('click',function(e){
        var url = $(this).attr("href");
        // Console logs shows the domain name of the link being clicked and the current window
        // console.log('e.currentTarget.host: ' + e.currentTarget.host);
        // console.log('window.location.host: ' + window.location.host);
        // If the domains names are different, it assumes it is an external link
        // Be careful with this if you use subdomains
        if (e.currentTarget.host != window.location.host) {
            // console.log('external link click');
            // Outbound link! Fires the Google tracker code.
            _gat._getTrackerByName()._trackEvent("Outbound Links", e.currentTarget.host.replace(':80',''), url, 0);
            // Checks to see if the ctrl or command key is held down
            // which could indicate the link is being opened in a new tab
            // Also checks if target="_blank" on the link tag which indicates it should always be opened in a new tab
            if (e.metaKey || e.ctrlKey || this.target == "_blank")) {
                // console.log('ctrl or meta key pressed');
                var newtab = true;
            }
            // If it is not a new tab, we need to delay the loading
            // of the new link for a just a second in order to give the
            // Google track event time to fully fire
            if (!newtab) {
                // console.log('default prevented');
                e.preventDefault();
                // console.log('loading link after brief timeout');
                setTimeout('document.location = "' + url + '"', 100);
            }
        }
        /*
        else {
            console.log('internal link click');
        }
        */
    });
});

Solution 3

The problem with window.open is that the referrer will be lost. A better solution is to use onmousedown instead of onclick. Having done some tests, I know this work better that using window.open or using setTimeout. You got some false positive from people clicking the right mouse button and not choosing "Open in new tab" or "Open in new window", but onclick doesn't always fire for middle and right click on all browser. It's a choice between the lesser of two evils here.

jQuery(function($){
  $('a:not([href*="' + document.domain + '"])').mousedown(function(event){
    // Just in case, be safe and don't do anything
    if (typeof _gat == 'undefined') {
      return;
    }

    var link = $(this);
    var href = link.attr('href');
    var noProtocol = href.replace(/http[s]?:\/\//, '');

    // Track the event
    _gat._getTrackerByName()._trackEvent('Outbound Links', noProtocol);
   });
});

Solution 4

use location.hostname instead of location.host . hostname does not include the port.

Solution 5

This small piece of code worked for me :

    var hostname = window.location.hostname; 

    jQuery("body a").click(function(){

          if(jQuery(this).attr("href").indexOf(hostname)== -1){

               ga('send', 'event', {'eventCategory': "Outbound Links", 'eventAction': "OnClick", 'eventLabel': jQuery(this).attr("href")});

          }
    });
Share:
13,182

Related videos on Youtube

Wallace Sidhrée
Author by

Wallace Sidhrée

I've been a gymnast for 5 years, boy-scout for 9, vegetarian for 25, a musician for 29... even a yogic-monk for nearly 10 years! I've been developing websites for 23 years and currently work as a Senior Frontend Developer at Netlife Design in Oslo, Norway. Netlife is one of the leading consultancy companies in Scandinavia, and is widely known for its strong UX and Frontend departments. Netlife basically introduced the concept of usability testing to the Norwegian market, solving critical challenges for demanding clients. If you Google me you'll find I'm also a musician. You'll discover links to my music (Spotify, Apple Music, etc). You're very welcome to take a listen! ;) PS: Some of these years overlap... I'm not that old!

Updated on June 05, 2022

Comments

  • Wallace Sidhrée
    Wallace Sidhrée almost 2 years

    I've been using a script to track outbound links for a couple of months now. The script WORKS, but in the report generated by Google Analytics many URLs are having a trailing ":80" (default port number) at their end. Read on for more details.

    It's maybe important to mention that the website tracking these outbound links has a tremendous amount of outbound traffic (multiply your fantasy by ∞).

    The script's purpose

    It tracks ALL outbound links and tag them as "Outbound Links" in Google Analytics.

    The script is heavily commented and has a few instances of console.log() to help debugging (these are kept commented out).

    "Outbound Links" show on GA alright, under:

    Content > Events > Top Events > "Outbound Links" [click on it] > [report showing all urls clicked]

    The problem

    Under the "Outbound Links" report, where I get all the links that were clicked, I get ":80" at the end of at least 2/3 of all links reported (probably more). GA treats http://example.com and http://example.com:80 as different links, separating them in the report. That's of course not desired.

    Worth mentioning:

    Links that end with ":80" always have more hits than their equivalent without ":80", anything from 40% to 60% more hits.

    The wanted solution

    • Merge the links that end with ":80" with those without it, OR
    • Avoid appending ":80" to links, if possible.
    • Bonus: Understand why we get links ending with ":80" at all.

    The script

    // Outbound Link Tracking with Google Analytics
    // Requires jQuery 1.7 or higher (use .live if using a lower version)
    $(function() {
        $("a").on('click',function(e){
            var url = $(this).attr("href");
            // Console logs shows the domain name of the link being clicked and the current window
            // console.log('e.currentTarget.host: ' + e.currentTarget.host);
            // console.log('window.location.host: ' + window.location.host);
            // If the domains names are different, it assumes it is an external link
            // Be careful with this if you use subdomains
            if (e.currentTarget.host != window.location.host) {
                // console.log('external link click');
                // Outbound link! Fires the Google tracker code.
                _gat._getTrackerByName()._trackEvent("Outbound Links", e.currentTarget.host, url, 0);
                // Checks to see if the ctrl or command key is held down
                // which could indicate the link is being opened in a new tab
                if (e.metaKey || e.ctrlKey) {
                    // console.log('ctrl or meta key pressed');
                    var newtab = true;
                }
                // If it is not a new tab, we need to delay the loading
                // of the new link for a just a second in order to give the
                // Google track event time to fully fire
                if (!newtab) {
                    // console.log('default prevented');
                    e.preventDefault();
                    // console.log('loading link after brief timeout');
                    setTimeout('document.location = "' + url + '"', 100);
                }
            }
            /*
            else {
                console.log('internal link click');
            }
            */
        });
    });
    
    • William Entriken
      William Entriken over 11 years
      Very valuable. Please consider showing the edited code for posterity.
  • Wallace Sidhrée
    Wallace Sidhrée over 11 years
    As you can see the function includes all anchor tags, so I needed to have a "fool proof" condition to compare the url in the link with the url of the current domain. That was the idea behind using if (e.currentTarget.host != window.location.host). I still need to do that check - or a similar one - because that's the only way to make sure that the event tracking in Google Analytics only happens when a link points outside the current domain. But thanks for pointing in the right direction. I'll push the changes tomorrow and approve your reply as soon as it is tested. ;)
  • Fresheyeball
    Fresheyeball over 11 years
    "approve your reply as soon as it is tested" <-- Love it.
  • Wallace Sidhrée
    Wallace Sidhrée over 11 years
    I found that your answer is only partly right. That's because what comes after "or" is not correct - considering the way we want to assign the category, action and label in GA. We don't want the action to be the same as label, which would happen if we used either e.currentTarget.href or $(this).attr("href") as action. With e.currentTarget.host.replace(':80',''), we get the domain only as action www.example.com, which works great for us. Reference Google Analytics Event Tracking Guide.
  • Wallace Sidhrée
    Wallace Sidhrée over 11 years
    Edit your answer and I'll approve it ;)
  • ScottE
    ScottE about 11 years
    window.open doesn't always omit the referrer: stackoverflow.com/questions/4762254/…
  • Philip Walton
    Philip Walton almost 11 years
    The main problem with "mousedown" is it won't work on some touch screens.
  • Sébastien Brodeur
    Sébastien Brodeur about 10 years
    "Some touch screen", can you be more specific?
  • nhinkle
    nhinkle almost 10 years
    Will the Ctrl key detection also detect if the middle mouse wheel is clicked on the link?