Getting Nginx with Backbone pushState and Slim Framework to work

806 views Asked by At

First time using Backbone's pushState and not getting it 100% working, so help would be appreciated. My needs are:

  1. Must work with deeply nested URLs both navigating to them from the default route and
  2. With direct linking (or page refresh) to deeply nested URLs
  3. Must be able to call my PHP backend API (using Slim Framework) properly with Backbone sync.

I was unable to get all 3 of these things working, although with Nginx rewrites I could achieve #1 and #2.

To achieve #1 I did the standard

location / {
    root   html;
    index  index.html index.htm index.php;

    try_files $uri $uri/ /index.html;
}

redirecting to index.html which is documented well.


However this does not work with #2. If I go directly to a nested URL like www.example.com/store/item123/subitem345 I would get errors being unable to load my require.js files, which were being looked for at www.example.com/store/item123/ . Naturally this is not right.

I could make #2 work with some rewrite rules that remove the unwanted part of the URL (the /store/item123 part). Is this correct? And if so, is there a universal rewrite to make this work?


I could never get #3 to work fully. Whenever I was in a nested route (e.g. store/someitem123/subitem345), Backbone would append the intermediate parts of the URL to backend API call, which would give a 404 naturally. So instead of the needed (/php/api/args/) I would get (store/someitem123/php/api/args).

There must be a way to either override Backbone's sync function or use an Nginx rewrite to remove the intermediate parts that aren't needed (the store/someitem123 part in my example). For reference I have to have this block in the Nginx configuration to make the backend calls work at all. But currently they will only work when in at routes that don't have deeply nested URLs.

location /php/ {
  try_files $uri $uri/ /php/chs_rest.php?$args;
}
1

There are 1 answers

2
Jeremy Kendall On

Looks to me like the crux of the issue is route URL rewriting. Based on the Slim documentation for nginx, your conf file is incorrect. See the nginx section here: http://docs.slimframework.com/#Route-URL-Rewriting.

EDIT: Updated to address OP comment below.

In your specific situation, the best recommendation I can make is to split the Backbone.js application and the Slim application into separate apps.

The popular Backbone Wine Cellar tutorial's sample application is an excellent example of this. The Slim portion of the app is a few years old, but it would make an excellent reference for building a current app.

The benefits of splitting the app are numerous, perhaps the largest of which is the fact that each app will be much closer to standard Backbone and Slim applications. The resources at your disposal for learning and problem solving would expand greatly, as blog posts and documentation and SO questions would apply directly to your applications. Future maintenance and continued development will be much easier.

I'm confident that the effort to split the applications would have an extremely high return on investment.