14

pushState support was introduced with Backbone.js' version 0.5 update.

From the backbone documentation:

Note that using real URLs requires your web server to be able to correctly render those pages, so back-end changes are required as well. For example, if you have a route of /documents/100, your web server must be able to serve that page, if the browser visits that URL directly. For full search-engine crawlability, it's best to have the server generate the complete HTML for the page ... but if it's a web application, just rendering the same content you would have for the root URL, and filling in the rest with Backbone Views and JavaScript works fine.

This may seem like a trivial question, but I'm wondering if anyone can help me with some specific (preferably express) node.js server code. How should I go about handling these routes? I'm a little confused.

Here's the relevant excerpt from my app's router module:

var Router = Backbone.Router.extend({
    routes: {
        '': 'index',
        'about': 'about'
    },
    index: function() {
        indexView.render();
    },
    about: function() {
        aboutView.render();
    }
});

var initialize = function() {
    var router = new Router;
    Backbone.history.start({ pushState: true });
}

return {
    initialize: initialize
};

I only have a top-level route and a route for an about page here. So how should I set up a node server that will allow me to navigate to:

domain.com
domain.com/about
domain.com/#/about // <- for browsers that don't support pushState
Atinux
  • 1,703
  • 15
  • 18
swaggler
  • 583
  • 2
  • 5
  • 13

1 Answers1

18

Explanation

First, you need to know that domain.com/#/about will call the '/' route of your server because it doesn't read the # fragment. Your server will render the base of your Backbone.js application and Backbone will trigger the 'about' route.

So, you need to declare two routes in Express JS:

  • /
  • /about

Code

app.get('/', function(req, res) {
    // Trigger the routes 'domain.com' and 'domain.com/#/about'
    // Here render the base of your application
});

app.get('/about', function (req, res) {
    // Trigger the route 'domain.com/about'
    // Here use templates to generate the right view and render
});

I recommend you 3 links for SEO compatibility with Backbone.js by Derick Bailey:

Atinux
  • 1,703
  • 15
  • 18
  • Excellent links, exactly what I'm looking for thank you. I'm still confused about one aspect of this whole dynamic though. Since I'm including a server-side route for `/about`, doesn't that mean that we're losing the benefit the hash and hashbang methods gave us? The fact that we don't have to fetch an entire response from the server. I'm not sure I'm understanding this 100% correctly. – swaggler Jan 20 '12 at 10:01
  • 1
    For example, the previous hash fragment of `#/about` would be interpreted by the browser as a request to `http://domain.com` and then the hash fragment would be handled by the browser, once the contents of the default document for example.com were loaded. This situation arrives only if you copy-past the url with the hash fragment in a new tab/window for example. I can't explain perfectly in English, so I recommand you to read the links and try the code to better understand :) – Atinux Jan 20 '12 at 10:11