Contact

Technology

Jul 12, 2012

Modularizing the SiteCatalyst JavaScript Library

Fernando Berrios

Fernando Berrios

Default image background

SiteCatalyst is a software as a service (SaaS) application offered by Adobe-owned Omniture, offering the standard battery of web analytics functionality (client-side data collection, analysis and reporting). It works by implementing the tried and tested technique of pixel tracking (a.k.a tag, web beacon, web bug), where JavaScript is used to create a request for an image to a server. This request will also contain a bit of extra information that will be used by the analysis part of SiteCatalyst to later build all the pretty graphics and reports.

The way that the JavaScript in charge of all this gets to your page is by adding a generated library to a directory on your site and copying and pasting a snippet of code provided in the SiteCatalyst dashboard to the page you want to track. After setting this up and adding all the custom tracking variables, properties and events, you are good to go.

Now, like I said earlier, this is a tried and tested technique, why the need for modularization? Why even bother reading the rest of this post? Well, recently I had to integrate SiteCatalyst into an extremly dynamic client-side heavy application that I developed as a replacement to an existing page. By dynamic I mean, a single-page application that differs substantially from the traditional approach of pages that the SiteCatalyst library was built for.

Since single-page applications do away with page linking and reloading, important analytics information that is usually gathered by measuring when the user enters and leaves a page (like clicking the Back/Forward buttons or clicking on links that navigates them away from the page) is lost. So, to get around this problem while maintaining the use of the stock SiteCatalyst library I resorted to wrapping the library in a module that I could use throughout my application code to track both page views and links.

On to the gritty technical details. My application was built using a Backbone.js base and RequireJS modules. So, the module and functions I will describe here are intended to be used as a RequireJS module, but can be easily modified for use in other module formats or as standalone functions.

Let’s start with the base structure of the module:

define([ 'domReady!', 'underscore.module', 'underscore.extensions', 's_code' ], function (document, _, _ext) { var module = window.s; return module; });

As you can see there are some dependencies for this module, the ones to note are ‘underscore.extensions’ and ‘s_code’. The first one is an Underscore.js extensions module that will be used to cut down a bit of the code in some of the functions. The second and most important is the generated s_code.js file that is generated in the SiteCatalyst dashboard. This s_code file contains all the SiteCatalyst required configuration and all the pixel tracking magic (to be honest there is so much obfuscated code in that library that I can’t tell what half of the stuff in there does, so yeah, magic). This line is important:

var module = window.s;

The s variable will have all the SiteCatalyst library functions under it, this object is defined and attached to the global scope in the s_code.js file. If window.s is undefined then the s_code.js file hasn’t been loaded or executed yet. After that, we define our wrapper functions for the important stuff.

function trackPageView(options) { var s = s_gi(s_account); s = _.extend(s, options); var s_code = s.t(); if (s_code) { document.write(s_code); } clearTrackingOptions(options); } function trackLink(trackOptions, linkOptions) { var s = s_gi(s_account); var linkType = _.isNullOrUndefined(linkOptions.linkType) ? "o" : linkOptions.linkType; var linkName = _.isNullOrUndefined(linkOptions.linkName) ? "" : linkOptions.linkName; var linkTrackEvents = _.isNullOrUndefined(linkOptions.linkTrackEvents) || !_.isArray(linkOptions.linkTrackEvents) ? [] : linkOptions.linkTrackEvents; s = _.extend(s, trackOptions); s.linkTrackVars = _.toSentence(_.keys(trackOptions), ",", ",") + ",events"; s.linkTrackEvents = _.toSentence(linkTrackEvents, ",", ","); s.tl(true, linkType, linkName); clearTrackingOptions(trackOptions); }

Once we have this in place, using them throughout our application code is a snap. For example, if using jQuery or any other function to execute when the DOM is ready, set up the config variables:

var scOptions = { pageName:"SiteCatalyst JavaScript Tagging Module", server:"server-name-01", channel:"", prop1:"", eVar1:"" };

And place a call like:

siteCatalyst.trackPageView(scOptions);

This will send a ‘page view’ request to SiteCatalyst. We can also manually make calls to trackPageView whenever events in your UI dictate it’s necessary. Link tracking is also very easy to use, we can automatically bind click events on specific links or any other elements with something like this:

function addLinkTracking() { var linkName = this.title; // Use the links title attribute as our link name. siteCatalyst.trackLink(scOptions, { linkName:linkName, linkTrackEvents:["event1"] }); } var trackableLinks = document.getElementsByClassName("trackable"); _.each(trackableLinks, function (element) { // ...and bind the tracking function to it's click event. element.addEventListener("click", addLinkTracking); });

Smart use of the trackLink function can be very useful in a single page application. In these types of applications there are usually complex UI elements and various different ways of executing different or even the same actions. By giving your control elements unique names (or even categories) you can later see which actions in your application are the most used and how they are executed.

Here are some additional links and references to help while you are implementing your own solution:

SiteCatalyst Debugger SiteCatalyst Tagging Overview

Conversation Icon

Contact Us

Ready to achieve your vision? We're here to help.

We'd love to start a conversation. Fill out the form and we'll connect you with the right person.

Searching for a new career?

View job openings