I remem­ber the first time I saw Omni­ture ClickMap place over­lays over the links, but­tons, and images on a page. It was impres­sive; even to a web ana­lyt­ics new­bie, it was clear that the abil­ity to see the most effec­tive areas of a page in terms of clicks and other met­rics so visu­ally can bring obvi­ous value. How­ever, I also remem­ber think­ing that I had no idea how ClickMap does what it does. It lit­er­ally seemed like magic. Unlike the data avail­able in the Site­Cat­a­lyst report­ing inter­face, which can be seen and eas­ily deci­phered and counted com­ing through in image requests as pages are viewed, the ClickMap data col­lec­tion and report­ing func­tion­al­ity was—and is, to many users—completely mysterious.

My goal in this post is to explain some of the intri­ca­cies of ClickMap data col­lec­tion and report­ing, in so doing, I will also offer a few tips to improve (or fix) ClickMap track­ing on your site.

At a rel­a­tively high level, ClickMap does some­thing like this:

When the page loads, the s_gi() func­tion is called. That func­tion attaches an onclick event han­dler to the document.body object so that ClickMap can track any page ele­ment that is clicked. The func­tion called when a link is clicked writes data about that link to a cookie (s_sq), which the Site­Cat­a­lyst code then reads on the next page view (or image request) going to the same report suite as the page con­tain­ing the link in ques­tion; this data is sent as part of that image request.

(Note that cus­tom links/file downloads/exit links will pass ClickMap data imme­di­ately; they do not require a sub­se­quent page load.)

The object ID will either be taken from the href prop­erty of the ele­ment, or from the onclick event han­dler if an s_objectID value is spec­i­fied there. If the for­mer, note that the entire value of the href prop­erty is used as the object ID. (See below for more infor­ma­tion on this!) The objec­tID is writ­ten 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 con­tain­ing the given link is passed in the “pid=” para­me­ter of the image request. ClickMap uses the page name to locate the data regard­ing links on the page; thus, if the page name changes—either per­ma­nently or sub­se­quent to the image request on the page—ClickMap may be unable to look up the data col­lected in order to build the over­lay on the page.

To deter­mine the object loca­tion, Site­Cat­a­lyst code uses the document.all() method to assign a numer­i­cal ID to each dis­tinct ele­ment on the page. This numer­i­cal ID is passed in the “oi=” para­me­ter on the image request. When build­ing over­lays, ClickMap searches the page for the numer­i­cal ID stored in the data for the given page.

How to improve ClickMap tracking/reliability using object IDs

If you’ve ever had con­cerns about your ClickMap data—Is ClickMap track­ing all of my links cor­rectly? Why do cer­tain promi­nent links not dis­play many clicks?—you’ve prob­a­bly heard about the s_objectID vari­able, which is imple­mented in the onclick event han­dler of your anchor tags and other click­able ele­ments. Omni­ture strongly rec­om­mends imple­ment­ing this vari­able, set to a unique ID for each link on the pages of your site, when­ever links appear not to be tracked cor­rectly. Why? Because it gives you com­plete con­trol over the gran­u­lar­ity of links on the page.

Here’s an exam­ple to help explain what I mean. ClickMap strug­gles with links that only dif­fer in their query strings; this typ­i­cally hap­pens on sites that use tem­plates to gen­er­ate pages dynam­i­cally, with the val­ues in the query string deter­min­ing the con­tent on the page (such as a generic prod­uct detail page where value in the query string tells your site which prod­uct to dis­play). Thus, you might have sev­eral links on the same page that all point roughly to the same place:

http://​www​.your​site​.com/​m​y​p​a​g​e​.​p​h​p​?​c​o​n​t​e​n​t​_​i​d​=​1​2​3​456

Based on the expla­na­tion of basic ClickMap func­tion­al­ity given above, we know that the code will try to use “http://​www​.your​site​.com/​m​y​p​a​g​e​.​p​h​p​?​c​o​n​t​e​n​t​_​i​d​=​1​2​3​456″ as the object ID. The prob­lem is that the query string will ulti­mately be stripped out by default dur­ing data pro­cess­ing. (This set­ting can be changed, but this also affects other aspects of data pro­cess­ing.) The result is that, when dis­play­ing data, ClickMap is left try­ing to fig­ure out which “http://​www​.your​site​.com/​m​y​p​a​g​e​.​php” link is which.

Of course, this isn’t a prob­lem if the s_objectID vari­able is imple­mented cor­rectly; it allows you to tell ClickMap that links are dis­tinct. You can use any method to gen­er­ate s_objectID val­ues, and a unique value should ide­ally be applied to each link on each page of your site, although these val­ues should be the same across dis­tinct page views, vis­its, and vis­i­tors (i.e., they should not change from one page view to the next, or from one visit to the next, etc.). The imple­men­ta­tion might look some­thing 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 over­lays, it has a much eas­ier time dif­fer­en­ti­at­ing links and attribut­ing clicks correctly.

Of course, we rec­og­nize that com­ing up with a sys­tem to add object ID val­ues to each and every link on your site may be far too much work. For this rea­son, Omni­ture has authored a JavaScript plug-in to dynam­i­cally assign object IDs to each link on your site. Because of a num­ber of sig­nif­i­cant effects that this plug-in can have on your imple­men­ta­tion, only Omni­ture Con­sult­ing can dis­trib­ute this plug-in and offer imple­men­ta­tion help and sup­port for it.

There is one more HUGE advan­tage to using the s_objectID vari­able, which is that it helps ClickMap work around changes to page con­tent and lay­out that would oth­er­wise impact the tool’s abil­ity to over­lay links cor­rectly. As men­tioned above, an impor­tant ele­ment of ClickMap data is the link loca­tion. I have seen dozens of cases where a change to page lay­out has altered a link’s loca­tion enough that ClickMap strug­gled to find it when dis­play­ing data.

Even seem­ingly minor dif­fer­ences between the way a page looked when ClickMap data was col­lected and the way it looks when data is dis­played can alter the num­ber of clicks that are shown, because ClickMap thinks in terms of the page ele­ment index returned by the document.all() method, and, par­tic­u­larly as design­ers, we typ­i­cally don’t. We may add five seem­ingly innocu­ous links to a left nav­i­ga­tion menu, think­ing that all we did was con­sume what had been white space. How­ever, in the world of ClickMap, what we have actu­ally done is bump every­thing else in the code down by five ele­ments. The page lay­out may be essen­tially unchanged, but ClickMap is impacted nonethe­less. Using the s_objectID vari­able helps to over­come this by telling ClickMap exactly what link to over­lay with any given data, (almost) regard­less of where it may now exist on the page.

(Closely related to this is the fact that s_objectID helps in resolv­ing ClickMap dis­crep­an­cies across browsers. For exam­ple, ClickMap does not have access to the ele­ment loca­tions in Fire­fox as it does in IE. While it is still able to track data in Fire­fox, it is not uncom­mon to see dis­crep­an­cies when com­par­ing against clicks reported by the IE ver­sion of ClickMap. Using s_objectID over­comes this just as it helps to over­come changes in page con­tent: by remov­ing the need for ClickMap to fig­ure out the ele­ment loca­tion on its own.)

How chang­ing page names affects ClickMap

As I described above, ClickMap uses the page name to orga­nize link clicks, so that it doesn’t con­fuse the data for two iden­ti­cal links that occur on sep­a­rate pages; the cur­rent s.pageName value is passed in the pid= para­me­ter 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. How­ever, because ClickMap data for a given link click in passed after the page loads, it is pos­si­ble for the s.pageName to have changed between the time that the page loaded (and the page view data was passed into Site­Cat­a­lyst) and the time that the link was clicked. The result is that ClickMap data will be asso­ci­ated with a page name that is dif­fer­ent from the one that the plug-in will detect when you view the page, mak­ing it impos­si­ble for ClickMap to dis­play data for the page.

This is par­tic­u­larly com­mon on sites that set the s.pageName vari­able within the s_doPlugins func­tion in the s_code.js file. This func­tion is called when the page loads, but it is also called when­ever a link is clicked (in order to set the ClickMap cookie). Let’s say you have the fol­low­ing code within s_doPlugins:

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

Now, assume that on your home page, s.pageName orig­i­nally receives a value of “Home Page,” and that s.prop7 stores the two-character coun­try code of the home page ver­sion 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 asso­ci­ated to this lat­ter value, but the ClickMap plug-in would see the for­mer value, and would there­fore be unable to tie the actual link clicks to the page.

How can you tell if this is affect­ing you? Run the JavaScript Debug­ger or a packet mon­i­tor­ing tool, on the page fol­low­ing a link click on a page that isn’t dis­play­ing 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 exam­in­ing, then this is the problem.

There are a few ways around it. Cer­tainly the best is not to set the s.pageName vari­able within the s_doPlugins func­tion. I’ve never seen a case where a user actu­ally wanted the s.pageName vari­able to change when a link was clicked, so set­ting the vari­able out­side of s_doPlugins is prefer­able. Another option would be to save a copy of the page in ques­tion as “web page, com­plete” 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.

Seg­ment­ing ClickMap data

This isn’t an imple­men­ta­tion tip, but it’s an impor­tant fea­ture nonethe­less. What many users may not know is that ClickMap data can be seg­mented using ASI, which Adam Greco described here. When you set up an ASI seg­ment (e.g., “vis­its where visit num­ber is greater than one,” to see return vis­its in their own report suite), the ClickMap data is included.

Using the exam­ple just given, if I set up an ASI slot to view return vis­its 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 vis­its only.

Hope­fully, this infor­ma­tion will help you devel­op­ers under­stand ClickMap “under the hood” so that when you are plan­ning a new or upgraded imple­men­ta­tion, you have a con­text for under­stand­ing what you’re see­ing (or will see) in ClickMap, as well as a frame­work for trou­bleshoot­ing issues that may arise. ClickMap is a giant topic, and I’m sure this won’t be my last post on this prod­uct. Still, as always, please don’t hes­i­tate to leave com­ments, ping me on Twit­ter (Omni­ture­Care), or e-mail me (omni­ture­care at omni­ture dot com) with any questions!

10 comments
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