Loading Google Analytics dynamically on document load

The following method is out-of-date. Better check the anwsers for the Stack Overflow question ‘How do I dynamically load Google Analytics JavaScript?’ for up-to-date instructions.

According to the Google Analytics Help Center, the tracking code segment of your Analytics website profile must be added into the bottom of your content, immediately before the </body> tag. Sure you remember those days when you were told to put it in the <head>, and to many people’s astonishment when Analytics had an outage of its service loads of websites were just loading and loading while the user were getting no response – kinda new shade of screen death.

Gluing a remote functionality of your website with JavaScript and handling it by your document load event handler ain’t a scrapped idea as Analytics tracking itself stands of a remote JS call. Then why to take risks?

The base functionality of a web application heavily based on JavaScript may require that the whole content, or at least the DOM to be loaded. If Analytics remains still embed in the HTML code another outage would obstruct the running of your JavaScript code attached to document or DOM load event hence breaking down your app. So how to separate essential functions from remote web statistics?

There are several ways to load and call Analytics on document load. In the following example I use Scott Andrew’s great addEvent wrapper to handle event attaching.

Tested under Internet Explorer, Mozilla compatibles and Opera. May not work under certain versions of Konqueror and Safari. To address this issue you can use delayed function call.

Function loadGA is responsible for loading the remote Analytics API. After browser responsed the proper status, we call callGA, which create another script container using DOM methods, which forces browser to run its content.

function callGA() {
    var s2 = document.createElement('script');
    s2.setAttribute('type', 'text/javascript');
    s2.text = '_uacct="UA-xxxx-x"; urchinTracker();';
    document.getElementsByTagName('body').item(0).appendChild(s2);

}

function loadGA() {
    var s1 = document.createElement('script');
    s1.setAttribute('id', 'googleanalytics');
    s1.setAttribute('src', 'http://www.google-analytics.com/urchin.js');
    s1.setAttribute('type', 'text/javascript');

    addEvent(s1, 'readystatechange', function () {
	    if ((s1.readyState == 'complete') || (s1.readyState == 'loaded')) {
		callGA();
	    }
	});

    addEvent(s1, 'load', callGA);
    document.getElementsByTagName('head').item(0).appendChild(s1);
}

addEvent(window, 'load', loadGA);

A pro of this method is that allows further refinement of your logic – e.g. you can now serve different Analytics code depending on the protocol if you use secure channel.

And that’s all, folks. Comments are welcome at DZone.