No posts for a few months so I figured I’d group a couple of things into a single post.


Last summer we migrated to Nginx for load balancing and it’s been fantastic. A few months later, Nginx released support for HTTP/2, which I’ve been salivating over ever since. We recently acquired some new servers that are much higher end than the ones we were using before. We migrated load balancing to these and took the opporunity to update Nginx to the latest and greatest while we were at it. This means we’re now live on HTTP/2 across the board – our own load balancers, plus our CDN (Cloudflare).

From some tests we ran, the only other analytics service (that we like to compare ourselves to) that supports HTTP/2 is Google Analytics.

Sticky table headers

When you scroll down a report, our navigation tabs have “stuck” to the top of the screen for quite a while now. But the table headers in most of the reports we have would disappear. Not a big deal before, but since we added all that yummy segments data to the reports last April, there’s a lot of colums to look at.

Today, we pushed up an update so the table headers will now stick to the bottom of the tabs when you scroll down, as you can see in the screenshot below.

This was tricky, because we use tables for these particular reports. (Don’t give us heck about using tables here, this is exactly what they were designed for and is pretty much the only place they’re used on our site). You can’t just add position:fixed to a table row element, so instead we worked out a solution where we clone the table and remove everything but the first row, and stick that to the top, right below the tabs. It works great!

Tracking code queue encoding issues fixed

When we released heatmaps in Oct 2012, we made a change to our tracking code to queue up certain types of beacons to make them more accurate (javascript events and goals) and more efficient (heatmaps).

The queue is stored in a cookie in JSON format, which is URL encoded, then decoded when the cookie is read. The bug was that there was an extra URL decode in there, which badly broke JSON-parsing when a URL or title had “quote” characters in them. What made it difficult to find and fix was that other areas of the tracking code, I had inadvertently worked around this bug, thinking it was just a feature of browsers that they always decoded cookies when reading them. Alas no, it was just my own damn fault.

This was a very uncommon bug to come across, but for the few people who emailed us about it over the years, it was really nasty. A fatal JSON parse would basically kill javascript entirely which could severely break a site with our code on it. Thankfully this is all fixed now.

White label iframe auto-sizing

This is only of interest to our white label customers since, for security reasons, we don’t allow Clicky itself to be included within an iframe – unless it’s a white label.

Why do we let white labels use iframes? Because it’s simply the best way to integrate the analytics reports into a company’s existing site, making it completely seamless. The problem is that you have to manually declare an iframe’s width and height, and as someone clicks around pages, the actual height of each page is going to change. Since some of our reports can get pretty tall, the best solution was to just set a ridiculously large height on the iframe so that it would never have to scroll internally.

Good news! Now we have added messaging support to pass a message to the parent document with the height of the iframe document as each new page loads. Full details are here.


There have been a ton of minor tweaks and bug fixes pushed up in the last 3 months as well. Sometimes there’s a longer period of time between blog posts than there used to be. Don’t worry, we’re not slacking. We generally only post when there’s a major new feature to talk about. There’s lot of things going on behind the scenes at any given time that aren’t necessarily of interest to our customers, but these things take away precious time, time that we wish we could spend 100% of writing code.