Backbone Router + RewriteRule not triggering route with a “/”

I convert all links from example.com/action to example.com/index.html#action which is then parsed by my Backbone router.

However, my new page, signup/:inviteAuthHash (eg. signup/9d519a2005b3dac8802d8e9e416239a1) is not working; the only thing that renders is my index.html, and none of my breakpoints in my router are met.

.htaccess:

# not a file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# example.com/home => example.com/index.html#home
RewriteRule ^(.+)$ index.html#$1 [L,QSA]

router.js

var AppRouter = Backbone.Router.extend( {
    routes : {
        /* PAGES */
        // beta
        'request_invite' : 'request_invite',
        'signup/:inviteAuthHash' : 'signup',

        // Default
        '*actions' : 'defaultAction'
    },

    /* PAGES */
    // eta
    request_invite : function() {
        new BetaLayout;
        new RequestInviteView;
    },
    signup : function(inviteAuthHash) {
        // validate auth hash
        if(!InviteRequest.isValidInviteAuthHash(inviteAuthHash))
            return this.defaultAction();
        else {
            new BetaLayout;
            new SignupView(SignupView);
        }
    },

    // Default
    defaultAction : function(actions) {
        app_router.navigate('request_invite');
        this.request_invite();
    }
});

var initialize = function() {
    app_router = new AppRouter;

    $('a').live('click', function() {
        var href = $(this).attr('href');

        // only navigate to real links
        if(href == undefined)
            return;

        // open in new window?
        if($(this).prop('target') == '_blank')
            return true;

        app_router.navigate(href, {trigger: true});

        return false;
    });

    Backbone.history.start({pushState: true});
};
return {
    initialize : initialize
};

Answers:

Answer

Can you try this .htaccess instead:

# not a file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
# example.com/home => example.com/index.html#home
RewriteRule (?!^index\.html)^(.+)$ /index.html#$1 [L,NC,R,NE]
Answer

I think there is another, in my opinion better solution to your problem: the use of pushState.

So what you do is

  1. change your server configuration so that all urls under example.com except your assets actually render index.html (my apache knowledge is rusty, but that should not be hard to do).
  2. change your call to Backbone.history.start to enable pushstate, and specify the root, Backbone.history.start({pushState: true, root: "/"}), see Backbone documentation

On browsers that support pushstate, the url will display as it should and everything works, on older browsers backbone will automatically convert it to a url with a hash.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.