Advanced tagging

What is heatmap_ext?

heatmap_ext is the way to extend how heatmap's tag works, in 2 ways:

  1. to configure/customize features (templates, conversion) that need information that only you know

  2. to improve heatmap recording accuracy on your pages: detection of clickable elements, current url, page title, …

    By default, heatmap's tag works well on most sites and is compatible with jQuery, MooTools, Prototype, Angular.js, Backbone.js, and more.

Disclaimer heatmap cannot be responsible if you write a heatmap_ext that does not work (or worse, break your site).

Where to include it?

heatmap_ext should be included before the generic tag:

<script>
heatmap_ext = {
	/* heatmap_ext options */
};
// generic tag below this line, please do not modify
(function(h,e,a,t,m,p) {
m=e.createElement(a);m.async=!0;m.src=t;
p=e.getElementsByTagName(a)[0];p.parentNode.insertBefore(m,p);
})(window,document,'script','https://u.heatmap.it/log.js');
</script>

Good to know Most examples below are written so they can be included as a sitewide script (by using regular expressions) to leverage browser cache. You can obviously generate server-side a different heatmap_ext for each page, but that's not recommended.

List of options

Feature setup & configuration: these options are mandatory to setup some advanced features of heatmap, that need more information than what's available in the page.

Recording accuracy improvement: these options are sometimes needed to improve heatmap (special library, AJAX without pushState)

getTemplates

This function should return an array, listing templates used on your site.
Each item of the array is an object with two properties:
name being the name of each template and
value a boolean indicating if the current page uses this template.

Paid only This feature is included only in the Premium and Enterprise plans, please upgrade to use it.

  • Signature: getTemplates: function(current_url) or getTemplates: array
    • current_url: string, the current url
  • Return type: array of objects like { name: string, value: boolean }

Examples

heatmap_ext = {
	getTemplates: function(current_url) {
		return [
			// Articles template for all urls like http://mysite.com/article/title-12345
			{ name: 'Articles', value: current_url.match(/\/article\/.+-\d+/i) }, 
			// Product template for all urls like http://mysite.com/product/product-name
			{ name: 'Product', value: current_url.match(/\/product\//i) }
		];
	}
};

getSessionName (conversion heatmap)

Returns the name of the session cookie to be set by heatmap on your domain to track conversions.

Note Do not implement this if you don't track conversions. By default, heatmap does not set any cookie on your domain.

To track conversions on your site, heatmap needs a session cookie set on your domain. This function allows you to choose a cookie name that does not conflict with your own cookies.
The cookie only contains a unique session id. Please do not alter nor delete this cookie: it will automatically expire at the end of each session or when the user closes his browser.

Paid only This feature is included only in the Premium and Enterprise plans, please upgrade to use it.

  • Signature: getSessionName: function() or getSessionName: string
  • Return type: string

Examples

heatmap_ext = {
	getSessionName: 'hmsid'
};
heatmap_ext = {
	getSessionName: function() { 
		return 'hmsid';
	}
};

getConversions (conversion heatmap)

This function should return an array listing all conversion events. Each conversion event should be represented by an object with two properties, name representing the name of the event and value its numeric value.

To allow you to control in depth how conversions are recorded, heatmap's tag calls this function:

  • on page load, getConversions(current_url) is called, with current_url being the current url.
    For instance to record the purchase value, you may implement this function on the checkout page and return the total value of the shopping cart.
  • when a click (or tap) is made, getConversions(current_url, clicked_elt) is called, with current_url being the current url and clicked_elt being the DOM element that has been clicked or tapped.
    For instance to count the number of newsletter subscriptions, you should implement this function to return 1 when current_url matches the subscription page and clicked_elt is the submit button.

Paid only This feature is included only in the Premium and Enterprise plans, please upgrade to use it.

Limitations You can only track 10 different conversions events per site

Note If you implement getConversions you must also define getSessionName.

  • Signature: getConversions: function(current_url, clicked_elt) or getConversions: object
    • current_url: string, the current url
    • clicked_elt: DOM element, the element that has been clicked or tapped
  • Return type: array of objects like { name: string, value: number }

Examples

heatmap_ext = {
	getConversions: function(current_url, clicked_elt) {
		if (current_url.match(/checkout\.php/)) {
			// Track each purchase value to get the total revenue
			return [ { name: 'Purchase Value', value: 12345 } ];
		} else if (current_url.match(/newsletter\.php/)) {
			if (!clicked_elt) {
				// Count +1 each time someone visit the subscription page
				return [ { name: 'Subscribe Start', value: 1 } ];
			} else if (clicked_elt.type=='submit') {
				// Count +1 each time someone actually subscribe the newsletter
				return [ { name: 'Subscribe Confirm', value: 1 } ];
			}
		}
	}
};

getAuthor

Returns the name of the author of the page.

You can implement this function if you want to be able to filter the Top pages list by author name. This is particularly useful for media sites where authors need to focus on optimizing their own articles.

Paid only This feature is included only in the Premium and Enterprise plans, please upgrade to use it.

  • Signature: getAuthor: function() or getAuthor: string
  • Return type: string

Examples

heatmap_ext = {
	getAuthor: 'Oprah Winfrey' /* why not ;) */
};
heatmap_ext = {
	getAuthor: function() {
		return $('a[rel=author]').text();
	}
};

altShiftH

When set to false disables the alt-shift-H keystroke to trigger the heatmap user interface.

You can set this property to false if you want to prevent your visitors from accidentally triggering the heatmap user interface by typing alt-shift-H. When set to false, the only way to trigger the heatmap user interface is to use the bookmarklet or the WordPress plugin. When undefined, or set to any other value different from false, the keystroke alt-shift-H will display the heatmap user interface.

  • Signature: altShiftH: boolean

Examples

heatmap_ext = {
	altShiftH: false /* disables the alt-shift-H keystroke */
};

recordDisabled

Disables all recording when set to true.

You should set this value to true in two main cases:

  1. to prevent your users statistics from being spoiled by your or your team's navigation, (e.g by filtering server-side over the user IP, cookies, …).

  2. if you want pages to be removed from the Top pages or to prevent pages from counting towards your monthly capacity (e.g. by filtering on the current url)

  • Signature: recordDisabled: function() or recordDisabled: boolean
  • Return type: boolean

Examples

heatmap_ext = {
	recordDisabled: true; // set to true when server-side code detects your own IP address
};
heatmap_ext = {
	recordDisabled: function() {
		return window.location.href.match(/a-page-nobody-cares-about\.html/);
	}
};

cleanupURL

This function must return a clean and canonical version of the url parameter.

In most cases, sites are optimised for SEO and use a canonical url for all pages and all links, so the urls extracted by heatmap are the correct urls.

Here are a few use cases when you would need to configure cleanupURL:

  • the urls of your site use many different query strings (like ?param1=value1&param2=value2…) or anchors (like #section)
  • the urls of your site carry some user-dependent context (user name, user id, session id, …).
  • the urls of your site include timestamps or random ids
  • your site uses indifferently http and https for all urls (if you don't configure cleanupURL, heatmap will see these as 2 different urls)

Note If you define cleanupURL you may also want to use it in getCurrentURL, in order to have a consistent cleaning code for the urls of the pages, and the urls inside the DOM.

  • Signature: cleanupURL: function(url)
    • url: string, the extracted url of the DOM element that received a mouse or touch event
  • Return type: string

Examples

heatmap_ext = {
	cleanupURL: function(url) {
		// remove any query param that do not affect the content of the page
		url = url.replace(/((tmstp|rnd|source|redir|userid|email)=[^&]*[&]?)/gi,'');
		// remove trailing ?&#
		url = url.replace(/[?&#]$/g,'');
		// map all url with https:// to http://
		url = url.replace(/^https:\/\/www\.mysite\.com/gi,'http://www.mysite.com');
		return url;
	},
	getCurrentURL: function() {
		return heatmap_ext.cleanupURL(window.location.href);
	}
}

getCurrentURL

This function must return a clean and canonical version of the current url.
The implementation of getCurrentURL is critical as heatmap's tag records interactions on a per-page basis, and the unique identifier for each page is its url.

In most cases, sites are optimised for SEO and use a canonical url for all pages and all links, so you don't need to implement this function. By default, heatmap's tag will simply use window.location.href as the current url.

Here are a few use cases when you would need to configure getCurrentURL:

  • your site/app uses AJAX and your pages work both as http://mysite.com/my-page and http://mysite.com/!#my-page
  • you have lots of similar pages that you want to group, and you don't want to have the individual data
  • you want to split statistics, based on external factors (A/B testing, window size, …)
  • etc. (see examples below)

Note If you define cleanupURL you may also want to use it in getCurrentURL, in order to have a consistent cleaning code for the urls of the pages, and the urls inside the DOM.

  • Signature: getCurrentURL: function() or getCurrentURL: string
  • Return type: string

Examples

heatmap_ext = {
	getCurrentURL: function() {
		// retrieve the html tag <link rel="canonical" href="..." />
		var links = document.getElementsByTagName('link');
		for (var i=0, max = links.length; i < max; i++) {
			var link = links[i], rel = link.rel || link.getAttribute('rel');
			if (rel == 'canonical') return link.href;
		}
	}
};
heatmap_ext = {
	getCurrentURL: function() {
		var url = window.location.href;
		// Tweak to record all interactions of all search result pages on a single virtual page
		url = url.replace(/search\.php(\?.*)/gi, 'search.php'); // remove all query parameters
		return url;
	}
};
heatmap_ext = {
	getCurrentURL: function() {
		// compute window width
		var width = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth);
		var device = (width >= 992 ? '#desktop': width >= 768 ? '#tablet': '#mobile');
		// Tweak to record interactions by screen size
		return window.location.href + device;
	}
};

getTitle

Returns the title of the page.

In most cases, you don't need to implement this function. Most sites use the <title> markup to specify the page title, and heatmap's tag will automatically collect it using document.title.

However, if you want heatmap's tag to use a different title than the one present in the page, you can force it by defining this function.
This is useful if your page has a different title for each different user

  • Signature: getTitle: function() or getTitle: string
  • Return type: string

Examples

heatmap_ext = {
	getTitle: $($('h1')[0]).text();
};
heatmap_ext = {
	getTitle: function() {
		// prevents the title of /my-profile/ to include the name of the logged-in user
		if (window.location.href.match(/\/my-profile\//) return 'User profile page';
	}
};

isActive

This function is called by heatmap's tag when an element is clicked or tapped and must return a boolean value:

  • true if the element reacts to mouse clicks or touch events,
  • false otherwise.

In most cases, you don't need to implement this function as heatmap's tag supports all native HTML elements like <A>, form elements, elements with onclick listeners, and major javascript libraries like jQuery, MooTools, Prototype, Angular.js, Backbone.js, and more…

In rare cases, heatmap's tag may fail to understand an active element, in such case the corresponding clicks are displayed by checking the Inactive clicks option in Sidebar > Settings. You can then implement isActive to return true for these elements. You must then also implement getURL for the same elements, and they will be considered by heatmap's tag like any other natively active element.

Please help us improve heatmap's tag: if you feel like your page contains standard elements that should be detected as active by default, please report it in the comment section at the end of this article. We'll contact you and investigate the issue.

  • Signature: isActive: function(elt)
    • elt: the DOM element that received a mouse or touch event
  • Return type: boolean

Note It is mandatory to implement isActive whenever you implement getURL.

Examples

heatmap_ext = {
	isActive: function(elt) {
		var t = elt.tagName, c = elt.className || '';
		if (elt.id && t=='DIV' && c.match(/ui-slider/)) return true;
		if (t=='LI' && c.match(/menu-item/)) return true;
	},
	getURL: function(elt) {
		var t = elt.tagName, c = elt.className || '';
		if (elt.id && t=='DIV' && c.match(/ui-slider/)) return elt.id;
		if (t=='LI' && c.match(/menu-item/)) return (elt.id || elt.innerHTML);
	}
};

getURL

This function is called by heatmap's tag when an element is clicked or tapped and must return a string, either:

  • a url
  • or a unique id

In most cases, you don't need to implement this function as heatmap's tag supports all native HTML elements like <A>, form elements, elements with onclick listeners, and major javascript libraries like jQuery, MooTools, Prototype, Angular, Backbone, and more…

In rare cases, heatmap's tag may fail to find the right url or id for an element.
If the DOM element is a link or any element navigating to a new page, then getURL should return the url to the target page.
If the DOM element is an active element that does not trigger any navigation (dropdown menus, sliders, layer zooming a picture, …) then getURL should return a string with a unique id representing the action. Any non-empty string is valid, but for best event recording we recommend to return an id that is unique at page level.

  • Signature: getURL: function(elt)
    • elt: the DOM element that received a mouse or touch event
  • Return type: string

Note It is mandatory to implement isActive whenever you implement getURL.

Examples

heatmap_ext = {
	getURL: function(elt) {
		var t = elt.tagName, c = elt.className || '';
		if (elt.id && t=='DIV' && c.match(/ui-slider/)) return elt.id;
		if (t=='LI' && c.match(/menu-item/)) return (elt.id || elt.innerHTML);
	},
	isActive: function(elt) {
		var t = elt.tagName, c = elt.className || '';
		if (elt.id && t=='DIV' && c.match(/ui-slider/)) return true;
		if (t=='LI' && c.match(/menu-item/)) return true;
	}
};