Tracking link exits

Jacob Lowe
3 min readDec 15, 2014

while preserving native browser functionality.

Here at Hone we have been strengthening our analytics and conversion metrics to give our customers the most insightful information about their audience. One useful event that we track is clicks to external sites. After searching for a good way to track our links, and not finding an elegant solution we decided to roll our own. We would like to share what we implemented.

The Issue

On the surface it sounds super simple to just listen to all the click events on a given page and try to log them to a rest API. It’s a bit trickier than that. The issue is that all the XHR calls will be canceled once the page changes.

The first solution we found is to grab the event, and call event.preventDefault then set window.location after we have tracked the event.

It looks something like this.

We were not a huge fan of this because it would take shift + clicks and ctrl + clicks and make them work the same way a normal click does when clearly that was not the user’s intent.

Our solution

We decided that the event needed to stay an event and dispatch again once we have tracked it.

Now it looks something like this.

What is nice about this approach is that now the click events will work as intended. Whenever a user ctrl + clicks it still works because with this approach we copy the event via new e.constructor( e.type, e ), so all the modifier keys are still intact when dispatching the event again.

Going further.

This is better but not a complete solution. There are a few things that would make this script a lot better.

Link disabling

Since we are deferring the navigation of the link there is a higher chance the user will click the link again. We do not want two events just because of a slow connection. So we temporary disable the link and re-enable it once we have dispatched the event.

Timeout

Sometimes an HTTP request can take more than 2 seconds. That is way too long for a user to wait after they have clicked a link. So instead of making the users wait, we will give the call a smaller amount of time to complete. It can be done by simply setting a short XHR timeout and then make sure xhr.ontimeout is handled. eg xhr.timeout = 1000

Filtering link clicks

With the window click events we will get a lot more events that are not anchor tag clicks so we filter all those out. We also track internal navigation a bit differently than external linking so we filter out those events.

Modifier handling

When a user is using a modifier key, lets say ctrl, tracking is not a problem because the page will not change. So instead of waiting we just dispatch those events right away.

Here is the full code:

Come work at Hone

Hone Inc is hiring for a number of positions.

--

--