1

I've set up a super simple Backbone app with just a router and two views to try and nail down the correct way to handle routing with no hashbangs.

var Router = Backbone.Router.extend({
    routes: {
        '': 'index',
        'episodes': 'episodes'
    },

    index: function () {
        var view = new IndexView();
        view.render();
    },

    episodes: function () {
        var view = new EpisodesView();
        view.render();
    }
});

var IndexView = Backbone.View.extend({
    el: $('#primary'),
    render: function () {
        console.log('index view');
    }
});

var EpisodesView = Backbone.View.extend({
    el: $('#primary'),
    render: function () {
        console.log('episodes view');
    }
});

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

I realize that the history object allows forward and backward navigation between pages, which is great. However, the way it's actually implemented seems a little messed up to me.

For instance, I created a simple MAMP server to serve an index.html file and the JS file. Navigating to http://backbone:8888/, the console logs index view like I'm telling it to. However, navigating to http://backbone:8888/episodes (by typing it into the address bar) returns a 404. BUT, if I navigate to http://backbone:8888/#episodes, the URL redirects to http://backbone:8888/episodes (without the hashbang) and I get episodes view logged to the console, which obviously means it's hitting that EpisodesView view.

From here, I can go back and forth between the index and episodes views. (back hits /, forward hits /episodes). That's all fine and dandy until I hit refresh while on /episodes again. 404...

So my question is this: how can Backbone be set up to handle URLs without relying on hashbangs? Everything I've found on the topic says "oh just pushState!". Well, I'm using pushState and, like I described above, you can't hit a URL like /episodes directly without getting a 404.

Trevan Hetzel
  • 1,371
  • 7
  • 21
  • 42
  • This is a server side issue. Apache is probably looking for index.html at the folder episodes in your web directory. Maybe you can try doing an Apache URL rewrite to your root index.html no matter what URL you go to. That's likely not a good long run solution since you're probably going to want to add some sort of server side logic (Node.JS, Python, Ruby, PHP, etc). Then you'd have to decide if you want to render the correct page on the server side among other issues. – Gohn67 Dec 30 '14 at 19:53

1 Answers1

1

When you use push state, pages are served from the back end, which means that you have to define a corresponding route in your back end that corresponds to a front end route.

If the back end doesn't find the requested route, then it will deliver a 404 message, because it won't know what to serve. In your case, the episodes view gets triggered at the front end level, but the browser doesn't have a DOM to render the view when the page gets refreshed because nothing was served.

By default, the route http://backbone:8888/ will serve the index file because this is how the webserver is configured.
I'm not sure what back end technology you are using, but for serving a file from http://backbone:8888/episodes, just make sure that your back end has a router set up that serves the requested route and it should work.

html_programmer
  • 18,126
  • 18
  • 85
  • 158