I think you are redefining the wrong: navigate not used the way you think.
Let's look at the Backbone.history.start part:
// Start the hash change handling, returning `true` if the current URL matches // an existing route, and `false` otherwise. start: function(options) { //... if (this._hasPushState) { Backbone.$(window).on('popstate', this.checkUrl); } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) { Backbone.$(window).on('hashchange', this.checkUrl); } else if (this._wantsHashChange) { this._checkUrlInterval = setInterval(this.checkUrl, this.interval); }
You will see that all the different ways of handling routing in Backbone go through checkUrl , not navigate . The checkUrl method does a bit of busy work and calls loadUrl ; One part of the busy work is this:
if (this.iframe) this.navigate(current);
therefore, navigate will be called, but only when <iframe> used to simulate hashchange and popstate and AFAIK events, which happens only when you use an older version of IE.
Return to the normal path through the code. We saw that checkUrl does some work and calls loadUrl , so what does it do? loadUrl does this :
loadUrl: function(fragmentOverride) { var fragment = this.fragment = this.getFragment(fragmentOverride); var matched = _.any(this.handlers, function(handler) { if (handler.route.test(fragment)) { handler.callback(fragment); return true; } }); return matched; }
If you look at the route method in History and route in route you will see that handler.callback is what calls the route handler from one of your routers and fires a routing event.
The navigate method you are replacing is heavily used by Router navigate :
navigate: function(fragment, options) { Backbone.history.navigate(fragment, options); return this; }
If you want to redirect before calling the route handler, you can replace loadUrl with something like this:
(function(History) { var _loadUrl = History.prototype.loadUrl; _.extend(History.prototype, { loadUrl: function() { var args = [].slice.apply(arguments); args[0] = this.getFragment(args[0]);
Demo: http://jsfiddle.net/ambiguous/e4KYK/
In general, I think that you better handle redirects in a regular route handler: when an offensive route is called, just call navigate on any router.
Keep in mind that Backbone.History not documented outside the start method, so everything here can be changed.