Skip to content
Browse files

changed hijack logic to only work on hash routes

  • Loading branch information...
1 parent 101f225 commit 13d15595d6bab2107a322aa083d22acd3d726959 @tbranyen committed Jul 13, 2012
Showing with 5 additions and 7 deletions.
  1. +5 −7 app/main.js
12 app/main.js
@@ -21,20 +21,18 @@ function(app, Router) {
// attribute, bypass the delegation completely.
$(document).on("click", "a:not([data-bypass])", function(evt) {
// Get the absolute anchor href.
- var href = $(this).prop("href");
- // Get the absolute root.
- var root = location.protocol + "//" + + app.root;
- // Ensure the root is part of the anchor href, meaning it's relative.
- if (href && href.slice(root.length) === root) {
+ var href = $(this).attr("href");
+ // If the href exists and is a hash route, run it through Backbone.
+ if (href && href.indexOf("#") === 0) {
// Stop the default event to ensure the link will not cause a page
// refresh.
// `Backbone.history.navigate` is sufficient for all Routers and will
// trigger the correct events. The Router's internal `navigate` method
// calls this anyways. The fragment is sliced from the root.
- Backbone.history.navigate(href.slice(root.length), true);
+ Backbone.history.navigate(href, true);

9 comments on commit 13d1559


why? i liked the previous behavior of using real links


I also liked the previous behavior.


This is something I'm not opposed to discussing. It was changed this way to ensure compatibility with pushState and the hash fallback. What are your reasons against it?


When I had yet to enable pushState, some of our users were e-mailing us complaining that URLs like weren't working. If they got to that page from the launch page, the url would have been . Clearly they were typing URLs manually. WTF, right? So I enabled pushState; now the # is gone from the URL, no more complaints. So, first point, I'd rather not have # in the URL because Joe User doesn't understand it.

I suppose I can change my current links (e.g. href="teams/<%= %>") to click events, and then have those events navigate to the appropriate fragment. But then, I gotta ask, why hijack links at all? Why not force everyone (that wants to avoid page reloads) to use click events bound to navigate?


I liked having templates just use simple links (for example, to /login/ or /forgotpassword/) rather than having to wire up events for it. Ideally the router would fallback to make those URLs navigate to their proper pages in the case of no-route-found, but the original implementation was good for my use case.

cbas commented on 13d1559 Jul 17, 2012

I also prefer the previous behaviour for several reasons.

  1. I want to be able to use the URL fragments for other purposes than Backbone routing. PushState serves that purpose better and hashes were always just a hack.
  2. I want my single-page app not to refresh on every internal, non-hash link click. Performance benefits of single-page apps are largely lost with this change.
  3. I don't want my users to see hashes in the link URLs. Hashes are ugly.
  4. I don't want users to bookmark hashes.
  5. I don't want to worry about a difference between hash or slash in my templates.
  6. I don't want SEO trouble.

That said, there was a bug in the original code that failed to catch links with authentication credentials. E.g. '' This fixes it:

var root = location.href.substr(0, location.href.indexOf('/', 8)) + app.root;

I think this change is largely misunderstood. Your users are not going to see hashes, this change did not affect how your routes are displayed. If you use hashes in your links, and then click on them Backbone Boilerplate will intercept and feed into navigate which will automatically use pushState or hash fallback. It's identical behavior to what existed before, the only difference is how the detection is made.

With this new information do you guys still find the old behavior better?

cbas commented on 13d1559 Jul 17, 2012

That only hides the hashes from the browser's location bar. Users will still see the hashes when hovering links, right click to copy the URL, drag the link to bookmark/paste. Google will presumably see and index the hashes. Developers need to use hashes in the templates. And URL fragments are not usable despite pushState support. I don't see how these issues are being addressed. Apologies if I'm mistaken.


The problem is I don't want to use hashes in my links, I want them to look like regular links. Also important for SEO (but even without SEO in mind I just want them to be regular links that COULD go to entirely separate pages but that backbone hijacks to use the router). If I had to opt-in my links somehow that would be okay if necessary.

Please sign in to comment.
Something went wrong with that request. Please try again.