Massimiliano Marini
Massimiliano Marini

Reputation: 499

Backbone pushState and error 404

I'm trying to implement the { pushState : true } but it works only for the base route, not with the other that continue to give me error 404.

In Chrome, If I access:

http://example.app/ - OK the console message is displayed

http://example.app/show - error 404 is returned

My route is

    var AppRouter = Backbone.Router.extend({

    routes: {
        '': 'index',
            'show': 'show'
        },

        index: function() {
            console.log('This is the index page');
        },
        show: function() {
            console.log('This is the show page');
        }

    });

    new AppRouter;
    Backbone.history.start({pushState: true});

My .htaccess

<ifModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !index
   RewriteRule (.*) index.html [L]
</ifModule>

What I'm missing or I'm doing wrong?

Upvotes: 7

Views: 2882

Answers (3)

McGarnagle
McGarnagle

Reputation: 102753

Remember that Backbone is a client-side framework -- if you're using path-based URLs for routing (push state), you still need to ensure that the server returns the correct markup for those URLs. This is summed up in the Backbone docs thusly:

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.

In other words, Backbone can't help you if your server doesn't understand example.app/show -- you have to fix the server, using a URL rewrite, and/or your server-side language of choice.

Upvotes: 14

royco
royco

Reputation: 51

I think you may just be missing the "#" in your url. I was following some tutorials now and I just realised that how they stop the request from going to the server.

So instead of
http://example.app/show
have
http://example.app/#/show

and backbone should be able to catch it.

Upvotes: -2

Shobhit Sharma
Shobhit Sharma

Reputation: 634

You need to create an initialize function for that case.

I hooked up something on Boilerplate router, just include this before initializing router in end of your script.

var initialize = function() {

    var app_router = new AppRouter;

    Backbone.history.start({ pushState: false });

    $(document).on('click', 'a:not([data-bypass])', function(e){

        var href = $(this).prop('href');
        var root = location.protocol + '//' + location.host + '/';

        if (root === href.slice(0, root.length)){
            e.preventDefault();
            Backbone.history.navigate(href.slice(root.length), true);
        }
    });

};

Upvotes: 0

Related Questions