The hasbang controversy

The other day I responded to a tweet about using prerendering tools to serve JS driven pages to crawlers.

Afterwards a twitter debate followed, and as usual, much is lost in a debate limited to 140 char chunks. Basically the opinion was that if you use hashbang urls, you are the spawn of the devil, and you will kill all the kittens in the world ;).

I will try to present my argument why I think using hasbang urls can be an acceptable solution to a specific problem.


For the purpose of an example, consider a company, Acme Cloth Inc, which is an imaginary online retailer of clothing. This company has a Shirts category on their website, which they want users to be able to filter in a nice manner. That means that the following features should work:

  1. When a filter has been applied, then the user should be able to bookmark it and share it
  2. The list should update without a page refresh, when a filter is set, to improve usability and performance
  3. The filtered url should be crawlable by search engines

The browser demographics statistics of the site show that 10% of the users us IE 8/9, and those users generate 20% of the revenue (these stats are from a real site at the time of writing)


In a modern browser, achieving the above objectives is not a problem. Using the pushstate browser API, it is entirely possible to update the url without causing a page refresh. For example, the url for a filtered page could look like /shirts/nike/green.

This is a very nice solution, which also makes the urls crawlable by default. The problem is that IE 8/9 do not support pushstate. Since those browsers are a big part of the revenue, we want to treat them at first class citizens in our website.

If we continue with the pushstate solution, then we will have to give up either the url history or the ajax loading of the products when filtered, but that also means that 10% of our users will get an inferior experience.

Enter the hasbang #!

The hashbang is a convention that Google supports, where you can specify that urls containing #! are actually JS driven pages, and then ask Google (and other bots) to fetch the page in a server rendered form, be requesting the hash as a query string. So a url like /shirts#!/nike/green would be requests by Googlebot like /shirts?_escaped_fragment_=%2Fnike%2Fgreen which would then tell you server to fetch the data directly instead of serving the Js driven page.

Why is this helpful? Well this invites IE 8/9 users to the party, since using hasbang url’s like /shirts#!/nike/green enables those browser to keep a history of the filter changes in the url, and bookmark those.

The downside is that when users load a page with a hasbang url, there will be a slight delay before the content is loaded, since in must be fetched by a separate ajax request. However this can be optimised, and you can work with perceived performance to improve the experience of that first page view. Subsequent filtering will be very snappy, because there will be no page refreshes.

Problem solved?

The hashbang solution lives up to the 3 criteria we set out with at the beginning. Also for the IE 8/9 users. In the case of Acme Cloth Inc, this means that we can provide a good service to a loyal customer group, which will most likely improve the revenue stream.

You can argue that this is not the “right” way to build websites, based on the way the web *should* work. It is a fair point, but I don’t think you should build a website just to satisfy you principles, you should build it to serve your users.

Is the hashbang a hack? Sure. Is it worth it to support user that supply 20% of your revenue? I think so! Should you use it on your website? That depends very much on your browser demographics. The pushstate solution is much cleaner, and is the future of the web, and you can decide if you think you can supply a service that is good enough for the IE 8/9 users, without either the history or the ajax features.

What about clients without JS? If you have significant number of this type of users, then you probably don’t wan to use hashbang urls. As always, use the solution that fits your problem.

There, that is my opinion on the matter, in more than 140 chars 🙂


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s