I remember the first time I saw Omniture ClickMap place overlays over the links, buttons, and images on a page. It was impressive; even to a web analytics newbie, it was clear that the ability to see the most effective areas of a page in terms of clicks and other metrics so visually can bring obvious value. However, I also remember thinking that I had no idea how ClickMap does what it does. It literally seemed like magic. Unlike the data available in the SiteCatalyst reporting interface, which can be seen and easily deciphered and counted coming through in image requests as pages are viewed, the ClickMap data collection and reporting functionality was—and is, to many users—completely mysterious.

My goal in this post is to explain some of the intricacies of ClickMap data collection and reporting, in so doing, I will also offer a few tips to improve (or fix) ClickMap tracking on your site.

At a relatively high level, ClickMap does something like this:

When the page loads, the s_gi() function is called. That function attaches an onclick event handler to the document.body object so that ClickMap can track any page element that is clicked. The function called when a link is clicked writes data about that link to a cookie (s_sq), which the SiteCatalyst code then reads on the next page view (or image request) going to the same report suite as the page containing the link in question; this data is sent as part of that image request.

(Note that custom links/file downloads/exit links will pass ClickMap data immediately; they do not require a subsequent page load.)

The object ID will either be taken from the href property of the element, or from the onclick event handler if an s_objectID value is specified there. If the former, note that the entire value of the href property is used as the object ID. (See below for more information on this!) The objectID is written to the s_sq cookie, and is read and passed on the next image request as described above.

The page name (or URL, if the page name is not defined) of the page containing the given link is passed in the “pid=” parameter of the image request. ClickMap uses the page name to locate the data regarding links on the page; thus, if the page name changes—either permanently or subsequent to the image request on the page—ClickMap may be unable to look up the data collected in order to build the overlay on the page.

To determine the object location, SiteCatalyst code uses the document.all() method to assign a numerical ID to each distinct element on the page. This numerical ID is passed in the “oi=” parameter on the image request. When building overlays, ClickMap searches the page for the numerical ID stored in the data for the given page.

How to improve ClickMap tracking/reliability using object IDs

If you’ve ever had concerns about your ClickMap data—Is ClickMap tracking all of my links correctly? Why do certain prominent links not display many clicks?—you’ve probably heard about the s_objectID variable, which is implemented in the onclick event handler of your anchor tags and other clickable elements. Omniture strongly recommends implementing this variable, set to a unique ID for each link on the pages of your site, whenever links appear not to be tracked correctly. Why? Because it gives you complete control over the granularity of links on the page.

Here’s an example to help explain what I mean. ClickMap struggles with links that only differ in their query strings; this typically happens on sites that use templates to generate pages dynamically, with the values in the query string determining the content on the page (such as a generic product detail page where value in the query string tells your site which product to display). Thus, you might have several links on the same page that all point roughly to the same place:

http://www.yoursite.com/mypage.php?content_id=123456

Based on the explanation of basic ClickMap functionality given above, we know that the code will try to use “http://www.yoursite.com/mypage.php?content_id=123456″ as the object ID. The problem is that the query string will ultimately be stripped out by default during data processing. (This setting can be changed, but this also affects other aspects of data processing.) The result is that, when displaying data, ClickMap is left trying to figure out which “http://www.yoursite.com/mypage.php” link is which.

Of course, this isn’t a problem if the s_objectID variable is implemented correctly; it allows you to tell ClickMap that links are distinct. You can use any method to generate s_objectID values, and a unique value should ideally be applied to each link on each page of your site, although these values should be the same across distinct page views, visits, and visitors (i.e., they should not change from one page view to the next, or from one visit to the next, etc.). The implementation might look something like this:

<a href=”http://www.yoursite.com/mypage.php?content_id=123456″ onclick=”var s_objectID=’mypage_link1′;”>

The result is that when the ClickMap plug-in tries to place overlays, it has a much easier time differentiating links and attributing clicks correctly.

Of course, we recognize that coming up with a system to add object ID values to each and every link on your site may be far too much work. For this reason, Omniture has authored a JavaScript plug-in to dynamically assign object IDs to each link on your site. Because of a number of significant effects that this plug-in can have on your implementation, only Omniture Consulting can distribute this plug-in and offer implementation help and support for it.

There is one more HUGE advantage to using the s_objectID variable, which is that it helps ClickMap work around changes to page content and layout that would otherwise impact the tool’s ability to overlay links correctly. As mentioned above, an important element of ClickMap data is the link location. I have seen dozens of cases where a change to page layout has altered a link’s location enough that ClickMap struggled to find it when displaying data.

Even seemingly minor differences between the way a page looked when ClickMap data was collected and the way it looks when data is displayed can alter the number of clicks that are shown, because ClickMap thinks in terms of the page element index returned by the document.all() method, and, particularly as designers, we typically don’t. We may add five seemingly innocuous links to a left navigation menu, thinking that all we did was consume what had been white space. However, in the world of ClickMap, what we have actually done is bump everything else in the code down by five elements. The page layout may be essentially unchanged, but ClickMap is impacted nonetheless. Using the s_objectID variable helps to overcome this by telling ClickMap exactly what link to overlay with any given data, (almost) regardless of where it may now exist on the page.

(Closely related to this is the fact that s_objectID helps in resolving ClickMap discrepancies across browsers. For example, ClickMap does not have access to the element locations in Firefox as it does in IE. While it is still able to track data in Firefox, it is not uncommon to see discrepancies when comparing against clicks reported by the IE version of ClickMap. Using s_objectID overcomes this just as it helps to overcome changes in page content: by removing the need for ClickMap to figure out the element location on its own.)

How changing page names affects ClickMap

As I described above, ClickMap uses the page name to organize link clicks, so that it doesn’t confuse the data for two identical links that occur on separate pages; the current s.pageName value is passed in the pid= parameter on the image request. When you visit your site and run the ClickMap plug-in, it first checks the s.pageName value on the page, then uses this page name to look up the click data. However, because ClickMap data for a given link click in passed after the page loads, it is possible for the s.pageName to have changed between the time that the page loaded (and the page view data was passed into SiteCatalyst) and the time that the link was clicked. The result is that ClickMap data will be associated with a page name that is different from the one that the plug-in will detect when you view the page, making it impossible for ClickMap to display data for the page.

This is particularly common on sites that set the s.pageName variable within the s_doPlugins function in the s_code.js file. This function is called when the page loads, but it is also called whenever a link is clicked (in order to set the ClickMap cookie). Let’s say you have the following code within s_doPlugins:

s.pageName=s.pageName+" : "+s.prop7

Now, assume that on your home page, s.pageName originally receives a value of “Home Page,” and that s.prop7 stores the two-character country code of the home page version that is being served up. On the page load, the final value of s.pageName might be “Home Page : UK.” But when the link is clicked, and s_doPlugins is called again, it would change to “Home Page : UK : UK.” The link click would be associated to this latter value, but the ClickMap plug-in would see the former value, and would therefore be unable to tie the actual link clicks to the page.

How can you tell if this is affecting you? Run the JavaScript Debugger or a packet monitoring tool, on the page following a link click on a page that isn’t displaying ClickMap data. If the pid= value in the image request on that next page doesn’t match the s.pageName value on the page you’re examining, then this is the problem.

There are a few ways around it. Certainly the best is not to set the s.pageName variable within the s_doPlugins function. I’ve never seen a case where a user actually wanted the s.pageName variable to change when a link was clicked, so setting the variable outside of s_doPlugins is preferable. Another option would be to save a copy of the page in question as “web page, complete” using your web browser and then hard-code the s.pageName to the altered value (e.g., “Home Page : UK : UK”), and run the ClickMap plug-in on the saved page with the altered page name, so that the tool is able to find the link data that was tied to the altered page name.

Segmenting ClickMap data

This isn’t an implementation tip, but it’s an important feature nonetheless. What many users may not know is that ClickMap data can be segmented using ASI, which Adam Greco described here. When you set up an ASI segment (e.g., “visits where visit number is greater than one,” to see return visits in their own report suite), the ClickMap data is included.

Using the example just given, if I set up an ASI slot to view return visits in their own report suite, I would then be able to visit my site using ClickMap and select the ASI slot from the “Site/Segment” drop-down menu to see click data for return visits only.

Hopefully, this information will help you developers understand ClickMap “under the hood” so that when you are planning a new or upgraded implementation, you have a context for understanding what you’re seeing (or will see) in ClickMap, as well as a framework for troubleshooting issues that may arise. ClickMap is a giant topic, and I’m sure this won’t be my last post on this product. Still, as always, please don’t hesitate to leave comments, ping me on Twitter (OmnitureCare), or e-mail me (omniturecare at omniture dot com) with any questions!

11 comments
DeepakKumar8
DeepakKumar8

Hi Ben,


I want to populate one prop variable with the value recorded in a clickmap to get an exhaustive list of all the links on the website. Could you please tel me what condition has to be put to do the same.


Thanks in advance

Ken
Ken

here are some update, the line of code below finally did show up when I deployed to my Dev environment sever, BUT after click 10 to 20 clicks, the clickmap overlay only report a few clicks (2 or 3), and i gave it enough time for the between clicks, so i guess once the onclick even triggered clickmap have to register that click count back to the Omniture DB and some where in between the count never make it to the DB. and this almost the same to all my other links which are the # of clicks doesnt equal to the # of count that click map report. Every page I checked the sourceview and all of my links have the s_objectID bind to an onclick event.

Ken
Ken

I have a question regard to assign an s_objectID on the TD onlick In the code behind, I assigned the s_objectID to the td onclick, and try follow/append by another fs function and that js return a false and the clickmap overlay never show up example: I tried these and it didnt work mylefttd.Attribute.Add("onclick", "s_objectID='lefttdclick'; return showslideupdiv('par1,'par2,'par3','par4')"); mylefttd.Attribute.Add("onclick", "s_objectID='lefttdclick'; showslideupdiv('par1,'par2,'par3','par4');return false"); mylefttd.Attribute.Add("onclick", "showslideupdiv('par1,'par2,'par3','par4';s_objectID='lefttdclick'; return false)"); and it works only when I assign the s_objectID by itself only meaning without the showslideupdiv('p1','p2','p3','p4') Any help is greatly appreciate

Chris Nelson
Chris Nelson

Hi Ben. Thanks for the response. Here's some more specific details on exactly whats happening: HTML input in question: So the s_objectID is directly after the "javascript:" and there is no "var" before or after. What we receive is a JS runtime error of "Class doesn't support Automation" and this occurs in the s_code.js at: {if(!o)return o;var n=new Object,x;for(x in o)if(x.indexOf('select')<0&&x.indexOf('filter')<0)n[x]=o[x];return n}; Specifically at "n[x]=o[x];" Even if I pare down the input to a simple straight-html that does nothing other than call Omniture code, the same JS error occurs: Would love your thoughts as it seems to be out of our control and within the core s_code?

Chris Nelson
Chris Nelson

Ben, here's an example site - http://humira.com - search box with "Go" input. Can't get that to show up in click map. The s_objectID/s.tl fix is not on prod. We did test on dev w/no success. Threw a JS error. Suggestions welcome! Tx.

Chris
Chris

Hi Ben. Quick question. Site search is something that is common on almost all sites. As such, many of our clients would like to include clicks on the site search "go/search" input within ClickMap reports. However, ClickMap seems to choke on particularly, inputs of a type "image". We've tried adding and s_objectID to the onclick area of the input. That didn't work. So, what other suggestions do you have to get image inputs showing up properly in ClickMap? It's a little mind-boggling because an input should register in the document.body as an element...? Note: Converting the to an actual image and using JS to do a form.submit() would be seen as a last ditch effort. (Involves rewrite of server side script used on a many sites.)

Jason
Jason

Ben, is there any talk of exposing the ClickMap raw data in the reporting api? It might be kind of fun to play around with developing your own heat map.

Ben Gaines
Ben Gaines

Jason: Great point. Thanks for sharing that.

Tony
Tony

It's good to know that last fact...didn't know that the Click Map would be specific for my ASI segment...it makes sense..just never gave it much thought - thanks for the head's up.

Jason
Jason

great post. I've done some testing with the s_objectID and it works great with one exception. If the s_objectID contains a "?" ClickMap fails to overlay the link properly. This becomes an issue when using the s_getObjectID plugin to automatically generate the set the s_objectID as the plugin makes use the destination URL to set the objectID. If your links contain query string parameters, ClickMap will still fail to overlay the links even though s_ObjectID is in use. To fix this, I added one line of code to the s_code.js file to swap any ''?" and "_" and it works great: ID=ID.replace("?","_");

Ben Gaines
Ben Gaines

Chris, The problem there, and with all <input type="image"> tags, goes back to something I mentioned in my post at http://is.gd/6CGJr. ClickMap does struggle at times with elements that use onclick functions (rather than hrefs) to do things. This is where s_objectID comes in handy. I'd be curious to hear what the JS error was when you tried this. A colleague and I tried it on the site you posted (using Firebug to add the "s_objectID='test'" and got it to work. The s_objectID implementation should come after "javascript:" and should not be preceded by "var." Once we did that, we saw the object ID pass successfully on the next page. Let me know if you have any better luck - and/or let me know what error it was throwing! Ben