My wife and I watched the movie High Fidelity on TV with friends over the weekend, so “top five” lists are on my brain. When I arrived at work on Monday, I immediately started brainstorming the top five implementation issues that make their way through the ClientCare organization here at Omniture.

My criteria in reviewing issues and coming up with this list were 1.) the frequency with which ClientCare sees the issue or something related to it and 2.) the trickiness of the issue. (For example, not referencing the s_code.js file correctly might be a common issue, but I’m not going to blog about it because it’s fairly easily caught, diagnosed, and solved by the rock stars manning phones, e-mail, and chat for ClientCare. It doesn’t make for very interesting discussion.)

The implementation problems I’ll explain below may or may not be affecting your site; because SiteCatalyst implementations vary so widely, even the most common problems do not come up all that often. Still, even if your current implementation seems perfect, knowing these “gotchas” may well save you from headaches in the future, and at the very least will hopefully explain some of the intricacies of the SiteCatalyst JavaScript code’s basic functionality.

1. Code in the <head> tag

Don’t do it. The attraction used to be that placing the SiteCatalyst code in between the <head> and </head> tags prevented the 1×1 pixel image that was returned by the request that sent data into our servers from affecting your page layout in any way, but this isn’t how the code works anymore. It now creates an image object—a non-visible image that doesn’t show up on your page at all. Beyond that, putting the code in the document head also means that the code appears earlier in the code, allowing it to execute sooner, which is significant inasmuch as it allows you to count page views for partial page loads more effectively.

Sounds great. But here’s the problem: Certain elements of the code require the existence of the body object. Since web browsers execute code in the order they receive it, if the SiteCatalyst JavaScript code is in the document head, then it executes before the body object exists. As a result, you don’t get ClickMap data. You don’t get automatic tracking of file downloads or exit links. You also don’t get Connection Type data or Visitor Home Page data. Technically, putting the code in the document head will work, but you’ll get a very limited version of SiteCatalyst and your users may begin to wonder why ClickMap isn’t displaying anything.

2. Use of s.linkTrackVars and s.linkTrackEvents

A few weeks ago, I wrote about link tracking, of which SiteCatalyst offers two basic versions: automatic and custom. Custom link tracking is generally used to track user actions, such as link clicks and interactions with Flash applications on your site; the automatic version tracks file downloads and exit link clicks for you.

Key to a successful link tracking implementation is an understanding of the s.linkTrackVars and s.linkTrackEvents variables, which allow you to pass custom variable values on these user actions. If you are implementing custom link tracking and want to pass variables and events, make sure that your s.linkTrackVars variable contains a comma-separated list of all variables that you will be passing, including the events variable. Make sure that s.linkTrackEvents includes a comma-separated list of all events that you will be passing. Note that setting s.linkTrackVars and s.linkTrackEvents does not actually set these variables/events; it only prepares the SiteCatalyst code to do so. You still need to set the variables manually, as shown in the example below.

Link Tracking Example

Notice that “events” is listed in the s.linkTrackVars variable; the individual events that may be passed are included in the s.linkTrackEvents variable and are also included within s.events. Each of the variables that are passed are listed in s.linkTrackVars before they are populated later in the function. 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 automatic file download and exit link tracking works differently. You have probably seen that s.linkTrackVars and s.linkTrackEvents are included in the basic s_code.js file that you received when you began your implementation, and both are set to “none.” You may have wondered why I am not recommending setting those variables within the global JavaScript file so that you do not need to worry about setting them when using custom link tracking. The reason is that automatic link tracking will use the s.linkTrackVars and s.linkTrackEvents values that you set in the global JavaScript file and will pass whatever the existing values of those variables are.

For example, 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 download a file, automatic file download tracking will pass data into SiteCatalyst, including the value of s.channel that was set on page load. “Home” will be passed a second time, leading to inflation in page view data for this value in the Site Sections report. This can be even more damaging

Thus we strongly recommend leaving the s.linkTrackVars and s.linkTrackEvents set to “none” in the global JavaScript file, and setting them explicitly as necessary with your custom link tracking implementation.

3. Seemingly innocent mistakes in s.products

I don’t think anyone would argue with me if I said that the s.products variable is the most syntactically complex variable that SiteCatalyst offers. Commas, semi-colons, pipes, and equals signs all play specific roles in the variable. It has no overall maximum length, but each individual product entry cannot be longer than 100 bytes. Mistakes in implementation of this variable are understandable, but unfortunately for developers s.products is often a site’s most important variable, as it makes possible the tracking of revenue, units, product names, etc.

This variable is explained in detail in the SiteCatalyst Implementation Manual and the online Knowledge Base, but here are a few extremely easy-to-make mistakes that can wreak havoc on any implementation.

Make sure that your category, product name, and revenue totals are devoid of commas and semi-colons. The comma is used to separate entries in the s.products string, as happens when you have two products in the same transaction; the semi-colon is used to delimit fields within an entry. If you use a comma or semi-colon in any other way, SiteCatalyst will assume that you are separating product entries. Consider the following example:

s.products=”widgets;large widget, 40’x40′;1;19.99,wugs;tiny wug;2;1,999.98″;

In this implementation, it is obvious that the developer intended for SiteCatalyst to read this as:

Category 1: widgets
Product 1: large widget, 40’x40′
Units 1: 1
Revenue 1: 19.99
Category 2: wugs
Product 2: tiny wug
Units 2: 2
Revenue 2: 1,999.98

However, note the commas in the “Product 1″ and “Revenue 2″ entries. These indicate a new product entry. SiteCatalyst would actually interpret the above as:

Category 1: widgets
Product 1: large widget
Category 2: 40’x40′
Product 2: 1
Units 2: 19.99
Category 3: wugs
Product 3: tiny wug
Units 3: 2
Revenue 3: 1
Category 4: 999.98

If you see a “1” as a line item in the Products report, this is almost certainly what is happening.

Make sure that your product and category names do not contain unsupported characters. This is especially difficult in the s.products string, because product names are often likely to contain characters such as ™, ©, and ®. These will need to be stripped out of the product and category values before they are placed into s.products. You will also need to make sure that currency symbols are not included in your revenue values. Supported characters are numbers 1-127 from the ASCII table.

4. White space in variable values

Take a look at the following example:

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

Looks innocent enough; we’re using document.title to populate s.pageName, so s.pageName should receive a value of “Home Page.” The problem is that not all browsers will interpret 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 leading white space, but others will not.

The result is that you will end up passing either this:

s.pageName="Home Page"

or this:

s.pageName="      Home Page"

and may not know it, until you notice that SiteCatalyst handles this scenario in an interesting way. It will treat these as distinct values, but the reporting interface will also strip out the leading white space. The result is a report which looks like this:

Pages Report

To make matters worse, SAINT does not allow leading white space in a key value, which means that it cannot be used to “group” multiple line items as a workaround if this issue is affecting your site. The only way to fix the problem is to pre-process the desired variable value (in this case, the title property) to remove any leading (or trailing, I might add) white space.

(Note that I am using the s.pageName variable with the document.title property as an example. Omniture does not recommend using document.title as the page name, nor does this issue only affect the s.pageName variable. Any variable that may have leading/trailing white space in its value can be affected.)

5. Not setting the offset when calling s.Media.play() and s.Media.stop().

This one pertains only to Media Tracking in JavaScript and ActionSource. Two key method calls that help you understand how end users are interacting with your videos are s.Media.play() and s.Media.stop(), which are similar in that they both require two arguments:

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

For example, when the user pushes the “Play” button initially, you might call s.Media.play(‘My_Video’,0). Now let’s say the user pauses the video after 10 seconds because he notices that he’s spilled coffee all over himself. There, you would call s.Media.stop(‘My_Video’,10). Once he’s cleaned himself up, he realizes he’s going to be late to a meeting 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 second argument, mediaOffset, may at first seem trivial. Its definition is “The number of seconds into the video that the play (or stop/pause, for s.Media.stop) occurs. Specify the offset based on the video starting at second zero.” Why is it important to tell the method at what point during playback the play/stop/pause event occurred? Well, in part because if this is not specified, the video data that is passed will be discarded. If this argument is left out of s.Media.play and s.Media.stop, the image requests that pass the video data into SiteCatalyst will contain “NaN” (which stands for “not a number”) values where these numbers should be, which tells SiteCatalyst that it doesn’t have valid information about the video playback.

If you are debugging this yourself, look for the pev3= parameter in the image request. If it ends with values such as S0E10S45E70, your implementation is sound. This can be interpreted as “started at zero, ended at 10 seconds; started again at 45 seconds, ended at 70 seconds.”

As I suggested at the beginning of this post, these issues may be affecting some of you, but the odds are that you haven’t run up against these issues in the past. If not, great. If so, hopefully this helped you understand what went wrong and how to get back on track. If you’ve got other issues that you’ve seen trip up otherwise successful implementations, I’d love to hear about them—some of them might even make for great blog posts (I won’t mention you or your company by name, of course!). Feel free to leave me a comment, or contact me via Twitter (OmnitureCare) or by e-mail (my twitter username at omniture 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.