My wife and I watched the movie High Fidelity on TV with friends over the week­end, so “top five” lists are on my brain. When I arrived at work on Mon­day, I imme­di­ately started brain­storm­ing the top five imple­men­ta­tion issues that make their way through the Client­Care orga­ni­za­tion here at Omniture.

My cri­te­ria in review­ing issues and com­ing up with this list were 1.) the fre­quency with which Client­Care sees the issue or some­thing related to it and 2.) the trick­i­ness of the issue. (For exam­ple, not ref­er­enc­ing the s_code.js file cor­rectly might be a com­mon issue, but I’m not going to blog about it because it’s fairly eas­ily caught, diag­nosed, and solved by the rock stars man­ning phones, e-mail, and chat for Client­Care. It doesn’t make for very inter­est­ing discussion.)

The imple­men­ta­tion prob­lems I’ll explain below may or may not be affect­ing your site; because Site­Cat­a­lyst imple­men­ta­tions vary so widely, even the most com­mon prob­lems do not come up all that often. Still, even if your cur­rent imple­men­ta­tion seems per­fect, know­ing these “gotchas” may well save you from headaches in the future, and at the very least will hope­fully explain some of the intri­ca­cies of the Site­Cat­a­lyst JavaScript code’s basic functionality.

1. Code in the <head> tag

Don’t do it. The attrac­tion used to be that plac­ing the Site­Cat­a­lyst code in between the <head> and </head> tags pre­vented the 1×1 pixel image that was returned by the request that sent data into our servers from affect­ing your page lay­out in any way, but this isn’t how the code works any­more. It now cre­ates an image object—a non-visible image that doesn’t show up on your page at all. Beyond that, putting the code in the doc­u­ment head also means that the code appears ear­lier in the code, allow­ing it to exe­cute sooner, which is sig­nif­i­cant inas­much as it allows you to count page views for par­tial page loads more effectively.

Sounds great. But here’s the prob­lem: Cer­tain ele­ments of the code require the exis­tence of the body object. Since web browsers exe­cute code in the order they receive it, if the Site­Cat­a­lyst JavaScript code is in the doc­u­ment head, then it exe­cutes before the body object exists. As a result, you don’t get ClickMap data. You don’t get auto­matic track­ing of file down­loads or exit links. You also don’t get Con­nec­tion Type data or Vis­i­tor Home Page data. Tech­ni­cally, putting the code in the doc­u­ment head will work, but you’ll get a very lim­ited ver­sion of Site­Cat­a­lyst and your users may begin to won­der why ClickMap isn’t dis­play­ing anything.

2. Use of s.linkTrackVars and s.linkTrackEvents

A few weeks ago, I wrote about link track­ing, of which Site­Cat­a­lyst offers two basic ver­sions: auto­matic and cus­tom. Cus­tom link track­ing is gen­er­ally used to track user actions, such as link clicks and inter­ac­tions with Flash appli­ca­tions on your site; the auto­matic ver­sion tracks file down­loads and exit link clicks for you.

Key to a suc­cess­ful link track­ing imple­men­ta­tion is an under­stand­ing of the s.linkTrackVars and s.linkTrackEvents vari­ables, which allow you to pass cus­tom vari­able val­ues on these user actions. If you are imple­ment­ing cus­tom link track­ing and want to pass vari­ables and events, make sure that your s.linkTrackVars vari­able con­tains a comma-separated list of all vari­ables that you will be pass­ing, includ­ing the events vari­able. Make sure that s.linkTrackEvents includes a comma-separated list of all events that you will be pass­ing. Note that set­ting s.linkTrackVars and s.linkTrackEvents does not actu­ally set these variables/events; it only pre­pares the Site­Cat­a­lyst code to do so. You still need to set the vari­ables man­u­ally, as shown in the exam­ple below.

Link Tracking Example

Notice that “events” is listed in the s.linkTrackVars vari­able; the indi­vid­ual events that may be passed are included in the s.linkTrackEvents vari­able and are also included within s.events. Each of the vari­ables that are passed are listed in s.linkTrackVars before they are pop­u­lated later in the func­tion. Also, as described above, I have included “event9” in s.linkTrackEvents, but have not included it in s.events. It will not be passed, but could be passed if I had included it in s.events.

Note that auto­matic file down­load and exit link track­ing works dif­fer­ently. You have prob­a­bly seen that s.linkTrackVars and s.linkTrackEvents are included in the basic s_code.js file that you received when you began your imple­men­ta­tion, and both are set to “none.” You may have won­dered why I am not rec­om­mend­ing set­ting those vari­ables within the global JavaScript file so that you do not need to worry about set­ting them when using cus­tom link track­ing. The rea­son is that auto­matic link track­ing will use the s.linkTrackVars and s.linkTrackEvents val­ues that you set in the global JavaScript file and will pass what­ever the exist­ing val­ues of those vari­ables are.

For exam­ple, let’s say that on page load, s.channel=“Home.” Now, let’s say that you have s.linkTrackVars=“channel” in your s_code.js file. If a user clicks to down­load a file, auto­matic file down­load track­ing will pass data into Site­Cat­a­lyst, includ­ing the value of s.channel that was set on page load. “Home” will be passed a sec­ond time, lead­ing to infla­tion in page view data for this value in the Site Sec­tions report. This can be even more damaging

Thus we strongly rec­om­mend leav­ing the s.linkTrackVars and s.linkTrackEvents set to “none” in the global JavaScript file, and set­ting them explic­itly as nec­es­sary with your cus­tom link track­ing implementation.

3. Seem­ingly inno­cent mis­takes in s.products

I don’t think any­one would argue with me if I said that the s.products vari­able is the most syn­tac­ti­cally com­plex vari­able that Site­Cat­a­lyst offers. Com­mas, semi-colons, pipes, and equals signs all play spe­cific roles in the vari­able. It has no over­all max­i­mum length, but each indi­vid­ual prod­uct entry can­not be longer than 100 bytes. Mis­takes in imple­men­ta­tion of this vari­able are under­stand­able, but unfor­tu­nately for devel­op­ers s.products is often a site’s most impor­tant vari­able, as it makes pos­si­ble the track­ing of rev­enue, units, prod­uct names, etc.

This vari­able is explained in detail in the Site­Cat­a­lyst Imple­men­ta­tion Man­ual and the online Knowl­edge Base, but here are a few extremely easy-to-make mis­takes that can wreak havoc on any implementation.

Make sure that your cat­e­gory, prod­uct name, and rev­enue totals are devoid of com­mas and semi-colons. The comma is used to sep­a­rate entries in the s.products string, as hap­pens when you have two prod­ucts in the same trans­ac­tion; the semi-colon is used to delimit fields within an entry. If you use a comma or semi-colon in any other way, Site­Cat­a­lyst will assume that you are sep­a­rat­ing prod­uct entries. Con­sider the fol­low­ing example:

s.products=“widgets;large wid­get, 40’x40’;1;19.99,wugs;tiny wug;2;1,999.98″;

In this imple­men­ta­tion, it is obvi­ous that the devel­oper intended for Site­Cat­a­lyst to read this as:

Cat­e­gory 1: wid­gets
Prod­uct 1: large wid­get, 40’x40’
Units 1: 1
Rev­enue 1: 19.99
Cat­e­gory 2: wugs
Prod­uct 2: tiny wug
Units 2: 2
Rev­enue 2: 1,999.98

How­ever, note the com­mas in the “Prod­uct 1″ and “Rev­enue 2″ entries. These indi­cate a new prod­uct entry. Site­Cat­a­lyst would actu­ally inter­pret the above as:

Cat­e­gory 1: wid­gets
Prod­uct 1: large wid­get
Cat­e­gory 2: 40’x40’
Prod­uct 2: 1
Units 2: 19.99
Cat­e­gory 3: wugs
Prod­uct 3: tiny wug
Units 3: 2
Rev­enue 3: 1
Cat­e­gory 4: 999.98

If you see a “1” as a line item in the Prod­ucts report, this is almost cer­tainly what is happening.

Make sure that your prod­uct and cat­e­gory names do not con­tain unsup­ported char­ac­ters. This is espe­cially dif­fi­cult in the s.products string, because prod­uct names are often likely to con­tain char­ac­ters such as ™, ©, and ®. These will need to be stripped out of the prod­uct and cat­e­gory val­ues before they are placed into s.products. You will also need to make sure that cur­rency sym­bols are not included in your rev­enue val­ues. Sup­ported char­ac­ters are num­bers 1–127 from the ASCII table.

4. White space in vari­able values

Take a look at the fol­low­ing example:

<head>
   <title>
      Home Page
   </title>
</head>
<body>
<script language="javascript">
      s.pageName=document.title
</script>

Looks inno­cent enough; we’re using document.title to pop­u­late s.pageName, so s.pageName should receive a value of “Home Page.” The prob­lem is that not all browsers will inter­pret this the same way because of the white space before “Home Page” in between the <title> and </title> tags. Some browsers will strip out this lead­ing white space, but oth­ers will not.

The result is that you will end up pass­ing either this:

s.pageName="Home Page"

or this:

s.pageName="      Home Page"

and may not know it, until you notice that Site­Cat­a­lyst han­dles this sce­nario in an inter­est­ing way. It will treat these as dis­tinct val­ues, but the report­ing inter­face will also strip out the lead­ing white space. The result is a report which looks like this:

Pages Report

To make mat­ters worse, SAINT does not allow lead­ing white space in a key value, which means that it can­not be used to “group” mul­ti­ple line items as a workaround if this issue is affect­ing your site. The only way to fix the prob­lem is to pre-process the desired vari­able value (in this case, the title prop­erty) to remove any lead­ing (or trail­ing, I might add) white space.

(Note that I am using the s.pageName vari­able with the document.title prop­erty as an exam­ple. Omni­ture does not rec­om­mend using document.title as the page name, nor does this issue only affect the s.pageName vari­able. Any vari­able that may have leading/trailing white space in its value can be affected.)

5. Not set­ting the off­set when call­ing s.Media.play() and s.Media.stop().

This one per­tains only to Media Track­ing in JavaScript and Action­Source. Two key method calls that help you under­stand how end users are inter­act­ing with your videos are s.Media.play() and s.Media.stop(), which are sim­i­lar in that they both require two arguments:

s.Media.play(mediaName, mediaOffset)
s.Media.stop(mediaName, mediaOffset)

For exam­ple, when the user pushes the “Play” but­ton ini­tially, you might call s.Media.play(‘My_Video’,0). Now let’s say the user pauses the video after 10 sec­onds because he notices that he’s spilled cof­fee all over him­self. There, you would call s.Media.stop(‘My_Video’,10). Once he’s cleaned him­self up, he real­izes he’s going to be late to a meet­ing and doesn’t have time to watch the whole video. He drags the progress bar to the 45-second mark and clicks “Play” again. This time, you would call s.Media.play(‘My_Video’,45).

The sec­ond argu­ment, mediaOff­set, may at first seem triv­ial. Its def­i­n­i­tion is “The num­ber of sec­onds into the video that the play (or stop/pause, for s.Media.stop) occurs. Spec­ify the off­set based on the video start­ing at sec­ond zero.” Why is it impor­tant to tell the method at what point dur­ing play­back the play/stop/pause event occurred? Well, in part because if this is not spec­i­fied, the video data that is passed will be dis­carded. If this argu­ment is left out of s.Media.play and s.Media.stop, the image requests that pass the video data into Site­Cat­a­lyst will con­tain “NaN” (which stands for “not a num­ber”) val­ues where these num­bers should be, which tells Site­Cat­a­lyst that it doesn’t have valid infor­ma­tion about the video playback.

If you are debug­ging this your­self, look for the pev3= para­me­ter in the image request. If it ends with val­ues such as S0E10S45E70, your imple­men­ta­tion is sound. This can be inter­preted as “started at zero, ended at 10 sec­onds; started again at 45 sec­onds, ended at 70 seconds.”

As I sug­gested at the begin­ning of this post, these issues may be affect­ing some of you, but the odds are that you haven’t run up against these issues in the past. If not, great. If so, hope­fully this helped you under­stand what went wrong and how to get back on track. If you’ve got other issues that you’ve seen trip up oth­er­wise suc­cess­ful imple­men­ta­tions, I’d love to hear about them—some of them might even make for great blog posts (I won’t men­tion you or your com­pany by name, of course!). Feel free to leave me a com­ment, or con­tact me via Twit­ter (Omni­ture­Care) or by e-mail (my twit­ter user­name at omni­ture dot com).

9 comments
Will Crowther
Will Crowther

Hey Ben, Great article! What is the normal way to enable Automatic link tracking for external links and downloads when you want to pass some custom information with the request without getting double results? Can the page request just be filtered out in the reporting? Right now the only way I can see to do it is to set the prop name in s.linkTrackVars, then populate the value of prop on the page. Will

Adam Kahtava
Adam Kahtava

Great post. It would be great if you guys could modify Omniture's JavaScript includes. Things like adding a namespace, removing the unneeded script postfix (), and offering an un-minified versions of your JavaScript resources would make a developers life easier. -Adam

RRS_ATL
RRS_ATL

Very handy info. Sure wish I had found this a few weeks back :\

Ben Gaines
Ben Gaines

Riann: Thanks for the comment. The 112/122 problem could definitely have been on this list; it's SO easy to miss, especially for developers implementing for multiple customers, some of whom may need 112 and others of whom may need 122 in s.dc. Your suggestion to always use a fresh set of code out of the Code Manager is a good one; it's the best way to make 100% sure that the s.dc value is correct. And you're right that the 1x1 pixel image doesn't really cause layout issues; it used to be a problem, but isn't one anymore. The code now creates an image object in the DOM that is not visible on the page. Problem solved.

Riaan Jacobs
Riaan Jacobs

Hi Ben, Great article and really clarifies the reasoning behind the implementation best practices. As noted, the incorrect path to the s_code.js include file is a very common mistake which is easily picked up by the SiteCatalyst JavaScript Debugger (which would immediately show that no image request has occurred) but what I did find also happens quite often is that the incorrect report suite id is used. Case in point, we had a client who mistyped "tourism" as "toruism" but was using the correct spelling for weeks before we noticed the error. Another uncommon one which we have encountered is that sometimes generic s_code.js files which have not been generated from the Code Manager in SiteCatalyst are sent to new clients and what happens is that the incorrect data collection server id for that account is used. That's why I insist on generating all new code for clients directly from the code manager for that specific report suite. With reference to your first point about having the 1x1 pixel affecting the layout of a web page, we have only encountered one client where it did actually affect the layout of their menu. They had tried numerous ways of embedding the pixel in their JavaScript includes etc. but we came up with a very simple solution. We placed the s_code.js include file within a tag whose z-index was above any of their existing CSS layouts and it worked perfectly. Looking forward to your further posts. Regards, Riaan

Jason
Jason

Another great post Ben. Can I tell you the the biggest implementation gotcha that I saw as an implementation consultant? Incorrect path to the JS file. Seemingly so simple, yet when errors occur it is often over looked to check the simple things. I can remember many calls going something like this: Client: omniture is broken Jason: the path to your JS file is incorrect Client: OMG, we have been looking at this for hours. thank you.

Matthew Niederberger
Matthew Niederberger

Hi Ben, Great little article on some of the pitfalls of a Sitecatalyst implementation. This is really useful. Those not implementing code everyday can use this as a mini refresher course of what points to consider when performing an implementation. It would be good to see more of these short, rich in knowledge articles! Take care, Matthew

Ben Gaines
Ben Gaines

Will, Great question. In fact, it's so great that several others asked something similar, leading a colleague and I to develop a little piece of code that helps you do just what you're suggesting. Take a look at my post entitled Enhancing Automatic Exit Links for the details. (Obviously, that code works for exit links, but not file downloads. It could easily be tweaked, however, to use s.linkDownloadFileTypes instead of s.linkInternalFilters, and to use 'd' instead of 'e' in the s.tl() function call.) One thing to note: Apparently, the blog shows the quotes in that code as smart quotes, which will break the JavaScript. Make sure to replace any smart quotes with straight quotes before deploying! Enjoy! Ben

Ben Gaines
Ben Gaines

Thanks for these suggestions, Adam. I know from personal experience that our JavaScript development team takes optimization very seriously. I'll make sure that they see your feedback here.