Fixing Google Analytics for Ghostery

As an avid user of Ghostery, which blocks all sorts of tracking scripts, pixels, and other web bugs I frequently run across a surprising issue: The case in which the Google Analytics ga.js script has been blocked from loading (which is intended) but then some critical piece of functionality on the site is broken. The most common place I see this is when a site adds some event tracking to a signup or purchase form. Clicking the submit button will result in a JavaScript error, thus making it impossible to submit the form.

I’ve found that this occurs when people are doing inline event tracking and are assuming that the Google Analytics functionality will always exist. Ghostery-or-not this is generally not a good practice to have: Assuming that some external, 3rd-party, script will always correctly load will result in many a broken web page.

You see cases where people work around this issue, for example in the HTML5 Boilerplate project:

<script src="//"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.1.min.js"><\/script>')</script>

This attempts to load the jQuery library directly from Google’s CDN and if it fails (for whatever reason — Google’s down, bad Internet connection, or some other weird reason) then it falls back to attempting to load a local version of jQuery. One question that comes of this is: Why not just always load jQuery from your local source rather than rely upon a third party? In this case it makes a lot of sense to pull jQuery from a CDN as you’ll benefit from the performance and caching benefits that a CDN provides, all while reducing the total bandwidth that you’ll have to expend on your end.

In the case of Google Analytics you typically don’t have that luxury: Google recommends that you load the ga.js library directly from their site (which can make sense as then they can push out seamless API changes and bug fixes). However this still causes issues for when Google Analytics simply doesn’t load, wether due to network conditions or due to Ghostery or some other browser extension.

For this reason, in a site I recently built, I added in the following code as a light wrapper around Google’s event tracking API:

// Add in Google Analytics tracking
var track = function(category, name, value) {
	if (window._gaq) {
		window._gaq.push(["_trackEvent", category, name, value]);

and then when I wanted to track an actual event I would do something like this:

track("Source", "Visit", this.href);

If Google Analytics has failed to load for some reason then the track() call just silently does nothing – and for users who have Google Analytics installed it tracks the event. I should note that this same technique applies for other event tracking APIs as well, such as Mixpanel or KISSmetrics (they’re blocked the same as Google Analytics).

Even libraries like, which act as a unified wrapper around tracking, are prone to the same issue. Even though they’ve gone through all the hard work of creating a unified API for event tracking they are still blocked by Ghostery, which will likely still result in errors in your application. In that case you would just write a similar track(...) wrapper around their analytics.track('Name', properties) call.

Update: The current version of the Google Analytics script always exposes the _gaq object, even if the code isn’t loaded, so this may be a non-issue for Google Analytics (although the principles here hold true for any third-party-included libraries). I’ve gotten word from the Ghostery team that Ghostery now handles this case, automatically exposing missing global objects for cases like this (see below in the comments). I’ve also gotten word from the team that, as of now, Ghostery does not block their analytics tracking so you may not need a wrapper there. Additionally does check to make sure that the potentially-blocked global objects are actually there before attempting to use them. In general though, and this goes for all third-party script, you’ll probably want to have a wrapper (or an alternative script) if you’re loading code from a third-party domain name.

Posted: February 8th, 2013

Subscribe for email updates

18 Comments (Show Comments)

Comments are closed.
Comments are automatically turned off two weeks after the original post. If you have a question concerning the content of this post, please feel free to contact me.

Secrets of the JavaScript Ninja

Secrets of the JS Ninja

Secret techniques of top JavaScript programmers. Published by Manning.

John Resig Twitter Updates

@jeresig / Mastodon

Infrequent, short, updates and links.