How to Create a Click Heat Map for Your Website using Google Analytics Event Tracking and Google Data Studio

CompassRed Data Labs
CompassRed Data Blog
8 min readAug 24, 2018
Photo by thr3 eyes on Unsplash

Have you ever seen one of those fancy heat maps that tools like Hotjar and CrazyEgg can produce, but were hesitant to pull the trigger on a $70+ monthly fee? Well I may have a solution for you using the free version of Google Analytics. This tutorial will take you through everything you will need to do to create a stunning visual like the one below. Prerequisites for this tutorial include a basic understanding of Google Analytics, Google Tag Manager, and Data Studio. There is some custom javascript involved, but all you will need to know how to do it copy and paste code. Let’s get started!

What Will My Heat Map Look Like When I’m Finished?

Here is an example of what I was able to create using this method:

What Can I Use a Click Heat Map For?

Heat mapping data is crucial for UX design decisions and gaining an understanding of how users are interacting with your website. You can spot trends in user actions (e.g. most users are clicking to X from the homepage) and identify friction points in the experience. Heat maps help drive the conversation within your organization because they are easy for everyone to understand and interpret. Having all of this data in GA also gives you the power to slice and dice your heat map by other user attributes like device, browser, purchasing behavior, source, etc. This tutorial covers the basic set up, but there are applications far beyond what is covered here. If this all sounds exciting and useful to you, please follow the three steps below to create your own click heat map.

Step 1: Create Your Click Events in Google Tag Manager

Create Your User-Defined Variables in Google Tag Manager

In order to capture all of the data we need for our report, we will have to create some custom javascript variables inside Google Tag Manager (GTM). I will outline each one below and explain what it does.

JS — Click Text Clean: This variable will provide us with a clean version of the text that a user clicks on. Make sure you have the built-in variable Click Text enabled before you set this one up. The code below checks to see if Click Text is defined, if it’s not, it will label your Click Text as ‘undefined’. The code also truncates Click Texts that are longer than 100 characters and converts everything to lowercase. You can use regular old Click Text if your prefer, but you may end up passing strings that are too long for GA to ingest and/or have funky case structures that lead to data splintering (GA is case sensitive).

function() {

var output;
var input = {{Click Text}};

if (input == null || input == ‘’) {
output = ‘undefined’;
} else {
if (input.length > 100) {
output = input.substring(0,100).toLowerCase() + ‘…’;
} else {
output = input.toLowerCase();
}
}

return output;
}

JS — Click X Coordinate: This variable will provide us with the mouse position along the x-axis (horizontal) where the user clicks. This is measured in pixels.

function() {

var coordinateX;

if (event == null) {
coordinateX = 0;
} else {
coordinateX = event.pageX;
}

return coordinateX;
}

JS — Click Y Coordinate: This is the same as the variable above except that it gives us the mouse click position along the y-axis (vertical).

function() {

var coordinateY;

if (event == null) {
coordinateY = 0;
} else {
coordinateY = event.pageY;
}

return coordinateY;
}

JS — Screen X Coordinate: This variable will provide us with the total width of the user’s viewport.

function () {

var body = document.body;
var html = document.documentElement;
var width = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth);

return width;

}

JS — Screen Y Coordinate: This variable will provide us with the total height of the user’s viewport.

function () {

var body = document.body;
var html = document.documentElement;
var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);

return height;

}

JS — Relative X Coordinate: Time for some fun math! We are taking the Click X Coordinate and dividing it by the Screen X Coordinate to create an index. This should adjust for the variability of different screen sizes.

function() {

var clickCoordinateX = {{JS — Click X Coordinate}};
var screenCoordinateX = {{JS — Screen X Coordinate}};
var relativeX;
relativeX = (clickCoordinateX / screenCoordinateX).toFixed(2);return relativeX;

}

JS — Relative Y Coordinate: We are doing the same thing as above, but for the Y Coordinate.

function() {

var clickCoordinateY = {{JS — Click Y Coordinate}};
var screenCoordinateY = {{JS — Screen Y Coordinate}};
var relativeY;
relativeY = (clickCoordinateY / screenCoordinateY).toFixed(2);return relativeY;

}

Those are all the custom variables you will need for this exercise.

Create Your Trigger

We will need to create a trigger in GTM to declare when our tag should fire and send data to GA. This might be the easiest step in this process. In GTM, create a new Trigger that fires on all Link Clicks. This is where you can get a little creative. If you would prefer to limit this Trigger to just a few pages (like your Home Page), you can add a condition to only fire on said pages. You can also experiment with an All Elements Trigger rather than just Link Clicks. In my tests, I found All Elements to pass too much extraneous data, so I limited mine to Link Clicks. Your Trigger should look something like this:

Create Your Tag

The last step in your GTM setup is creating your GA Event Tag. You have some liberties with how you name your Event Category and Action, but I advise to stick to my Event Label structure to make the rest of the tutorial easy to follow.

Event Category: heat mappingEvent Action: clickEvent Label: pu:{{Page URL}}|ct:{{JS — Click Text Clean}}|rx:{{JS — Relative X Coordinate}}|ry:{{JS — Relative Y Coordinate}}

^ umm.. what? You might be thrown by that Event Label. Let me breakdown what is being collected and why. First of all, the structure of the Event Label is setup so that it is easy to split by delimiter ‘|’ (pipe character) later on in Data Studio or whatever data viz tool you choose to use. I also use key value pairs to make it easy to remember what each delimited space represents. Here is an example of the output:

pu:www.compassred.com/ //user was on the CompassRed Home Page when this event occurredct:about //user clicked on the About link on the Home Pagerx:0.50 //the user clicked in the middle of the page along the x-axisry:0.05 //the user clicked 5% of the way down the page

Once you are satisfied with your tag settings, be sure to Preview your work and Publish.

Step 2: Verify Your Data in Google Analytics

Once you have Published your changes in GTM, be sure to head over to Google Analytics Real-Time reporting to see your newly created data funneling into your Property. You will want to make sure all the data points are passing through as expected — be sure to check your Event Label with extra scrutiny because that is the most important piece of the puzzle.

If everything looks good, then move on to Step 3.

Step 3: Build Your Report in Google Data Studio

You are welcome to use any reporting tool you would like, but I chose Data Studio for this tutorial because it is free and pretty simple to set up.

Create a New Report and Connect to Your GA Account

Navigate to datastudio.google.com and click the big blue + button to create a new report. You will be prompted to connect to a Data Source. Choose Google Analytics and then find the Account > Property > View where your newly created data exists.

Create Custom Fields

Remember that long Event Label string we created in GTM? Well it is time to break it apart into individual pieces. I have to admit that Data Studio does not make this easy, but if you followed my naming conventions exactly, then you should be able to copy and paste the functions below without error.

Open the Data Source Editor — you can get to the Data Source Editor a few ways. One way is to click on Resource > Manage added data sources in the top level navigation. Once you’re there click Edit on the appropriate Data Source.

For all the Custom Fields below, click on the Add a Field button, give your custom field a name, paste in the code I provide, and click Save.

Event Label — Page URL: This extracts the Page URL from your Event Label.

REGEXP_EXTRACT(Event Label,’pu:(.*?)(\\||$)’)

Event Label — Click Text: This extracts the Click Text from your Event Label.

REGEXP_EXTRACT(Event Label,’ct:(.*?)(\\||$)’)

Event Label — Relative X: This extracts the Relative X Coordinate from your Event Label.

REGEXP_EXTRACT(Event Label,’rx:(.*?)(\\||$)’)

Event Label — Relative Y: This extracts the Relative Y Coordinate from your Event Label.

REGEXP_EXTRACT(Event Label,’ry:(.*?)(\\||$)’)

The last thing you will need to do is Duplicate your Event Label — Relative X and Event Label — Relative Y custom fields. The reason for this is so you can store one version as Text and the other as a Number. Once you duplicate those two custom fields, be sure to convert them into numbers and give them new names so you can distinguish between the two versions. Here is what your final custom field list should look like:

Create Your Heat Map Visualization

It’s finally time to create your visualization. Before we get started, you will need a screenshot of whatever page you want to analyze. I use the Fireshot Chrome Extension, which is free and allows you to capture the entire webpage at one time and save it as an image.

Once you have your screenshot, insert it as an image on your dashboard and size it appropriately.

Next, create a scatter plot visual and add the following fields to your visual:

Styling is largely up to you, but there are a few things you will definitely want to do:

Flip the Y axis so that 0 starts at the top, which will match how your data was collected. Remove all the axis labels, gridlines, legends, etc. I would also recommend decreasing the size of the bubbles and adjusting the opacity of the overall chart to 50–70% so that the background is visible.

Finish off your visual by overlaying it on top of your screenshot that you inserted. This part will take a little adjusting, but if you have a lot of data, it won’t take long to get it in the right spot.

Congratulations! You have successfully created a click heat map from scratch using only free tools and a little bit of custom code.

I hope you found this tutorial helpful. Consider following Patrick Strickler and CompassRed Data Labs to stay up to date on when we publish new content.

--

--