React-router: Routing does not work with location="history"

Created on 14 Aug 2014  路  5Comments  路  Source: ReactTraining/react-router

<Routes>
  <Route handler={Home}>
    <Route name="about" handler={About}/>
  </Route>
</Routes>

Going to localhost:8000/#/ & localhost:8000/#/about do the right thing

Adding location = "history" to routes breaks down localhost:8000/about throwing 404

Most helpful comment

For others who get stuck while adding server side pushState with nginx, the directive in the readystate4 link above does not work for me. After some tinkering the following works for me:

With app routes:

/
/foo
/foo/bar
/foo/bar/baz
/foo/bar/baz/123
/tacos
/tacos/123

Use:

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;

    gzip_static on;

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

    # Attempt to load static files, if not found route to @rootfiles
    location ~ (.+)\.(html|json|txt|js|css|jpg|jpeg|gif|png|svg|ico|eot|otf|woff|woff2|ttf)$ {
      try_files $uri @rootfiles;
    }

    # Check for app route "directories" in the request uri and strip "directories"
    # from request, loading paths relative to root.
    location @rootfiles {
      rewrite ^/(?:foo/bar/baz|foo/bar|foo|tacos)/(.*) /$1 redirect;
    }
}

See my stackoverflow answer.

[Edit: changed to accommodate directory depth]

All 5 comments

You need a server that knows how to do this.

Check out our project http://github.com/rackt/react-boilerplate, it uses this to serve your app from any route: https://www.npmjs.org/package/pushstate-server

Additionally, you can do this with apache, nginx, etc. http://readystate4.com/2012/05/17/nginx-and-apache-rewrite-to-support-html5-pushstate/

For others who get stuck while adding server side pushState with nginx, the directive in the readystate4 link above does not work for me. After some tinkering the following works for me:

With app routes:

/
/foo
/foo/bar
/foo/bar/baz
/foo/bar/baz/123
/tacos
/tacos/123

Use:

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;

    gzip_static on;

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

    # Attempt to load static files, if not found route to @rootfiles
    location ~ (.+)\.(html|json|txt|js|css|jpg|jpeg|gif|png|svg|ico|eot|otf|woff|woff2|ttf)$ {
      try_files $uri @rootfiles;
    }

    # Check for app route "directories" in the request uri and strip "directories"
    # from request, loading paths relative to root.
    location @rootfiles {
      rewrite ^/(?:foo/bar/baz|foo/bar|foo|tacos)/(.*) /$1 redirect;
    }
}

See my stackoverflow answer.

[Edit: changed to accommodate directory depth]

@pxwise confirm works.

If looking for something a little more flexible, this also works:

server {
      root /usr/share/nginx/html;

      location ~ (?:.+\/)((?:.+)\.(?:.+)) {
        # $1 is the filename
        try_files $uri /$1 /css/$1 =404;
      }

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

Since there may be ajax request api, the following suits for this case,

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;

    # Any route containing a file extension (e.g. /devicesfile.js)
    location ~ ^.+\..+$ {
        try_files $uri =404;
    }

    # Any route that doesn't have a file extension (e.g. /devices)
    location / {
        try_files $uri /index.html;
    }

    # The location block above provides the shortest prefix, of length one, 
    # and so only if all other location blocks fail to provide a match, 
    # this block will be used.

    # Ajax api starts with /v1/ will be proxied
    location /v1/ {
        proxy_pass http://proxy;
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ArthurRougier picture ArthurRougier  路  3Comments

ryansobol picture ryansobol  路  3Comments

alexyaseen picture alexyaseen  路  3Comments

stnwk picture stnwk  路  3Comments

Radivarig picture Radivarig  路  3Comments