'React-router "Cannot GET /*" except for root url

I am willing to use React-router for my application, and I am trying the example given in the doc first, which I copied below. Now when I go to localhost:3000/, I see "App" as expected, but every other page, such as localhost:3000/inbox returns "Cannot GET /inbox". What am I missing here ?

var About = React.createClass({
  render: function () {
    return <h2>About</h2>;
}});

var Inbox = React.createClass({
  render: function () {
    return <h2>Inbox</h2>;
}});

var App = React.createClass({
  render () {
    return (
      <div><h1>App</h1>
        <RouteHandler/>
      </div>
)}});

var routes = (
  <Route path='/' handler={App}>
    <Route path="about" handler={About}/>
    <Route path="inbox" handler={Inbox}/>
  </Route>
);


Solution 1:[1]

If you are using webpack-dev-server there is an option called history-api-fallback. If set to true 404s will fallback to /index.html.

Add the option to devServer section of the Webpack config like this:

devServer: {
    contentBase: 'app/ui/www',
    devtool: 'eval',
    hot: true,
    inline: true,
    port: 3000,
    outputPath: buildPath,
    historyApiFallback: true,
},

Link to Webpack docs: https://webpack.js.org/configuration/dev-server/

webpack-dev-server docs on Github: https://github.com/webpack/webpack-dev-server

Solution 2:[2]

Simplest option: use hash history instead. The urls stay are not very nice and if you need better SEO, I'd opt for server-side rendering as well.

If you're interested in detail about this, this answer was really helpful for me: React-router urls don't work when refreshing or writting manually

Solution 3:[3]

The request will be sent to the server, and the directory/file does not really exists so it will return 404, so you have to tell the server to return the index page for all requests, and react will handle the rooting :

if like me, you are hosting your react app on IIS, just add a web.config file containing :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" path="/" responseMode="ExecuteURL" />
    </httpErrors>
  </system.webServer>
</configuration>

This will tell IIS server to return the main page to the client instead of 404 error.

Solution 4:[4]

I came across the same problem, if you have a server that responds to requests and a HashRouter if you are using a static file server. Instead of using BrowserRouter use HashRouter its not the perfect fix, but should solve the cannot GET "/path" error. be sure to import HashRouter from 'react-router-dom'

render() {
    return (
        <div>
            <HashRouter>
                <Blog />
            </HashRouter>
        </div>
    );
}

source: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/guides/basic-components.md

Solution 5:[5]

To add to those not helped by the answer: historyApiFallback: true works only for the first level of the url. So site.com/about will be redirected to index but site.com/about/me won't be. In this case, you need to add the rewrite option:

historyApiFallback: {
  rewrites: [
    { from: /./, to: '/index.html' }
  ]
}

This will match using a Regex expression all routes. Take care to also add this:

  output: {
    // ...
    publicPath: '/'
    //...
  },

Otherwise, the redirect will work to index.html, but index.html may have just bundle.js as the webpacked script, and will not read correctly. It should instead be '/bundle.js', which this config option will do.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 NM Pennypacker
Solution 2 Capuchin
Solution 3 Chtioui Malek
Solution 4 tony2tones
Solution 5 David Min