6

I'm using react, react-router(v4), redux and webpack(-dev-server) to build an app. The Devserver and eveything works fine, including HMR and historyApiFallback. Means that when I enter http://localhost:8080/how I get index.html, bundle.js (my app), and the right component How is being rendered.

My basic Routing looks as followed:

//App.js 
<Router>
    <Wrapper>
        <Route path='/' component={MainNav} />
        <Route exact path='/' component={Splash} />
        <Route path='/how' component={How} />
        <Route path='/auth' component={Auth} />
        <Route path='/' component={Footer} />
    </Wrapper>

However, when declaring a child route, e.g. in Auth:

<Wrapper orange>
    Login Page
    <Link to={loginUrl}>Login</Link>
    <Switch>
        <Route exact path='/auth/login' component={Login} />
        <Route path='/register' component={Register} />
    </Switch>
</Wrapper>

I get a 404 from react-router when entering http://localhost:8080/auth/login. When navigating to http://localhost:8080/auth/login within the App, e.g. on a Link click, the Login Component is being rendered.

I know there are a lot of similar questions on StackOverflow, but the strange thing is that top-level Routes are being rendered without a problem, this occurs only on nested routes. Also, it's probably not a problem with webpack-dev-server (historyApiFallback or publicPath), because I can also bundle the app for production and serve it with a node server, same result.

Also I dont see a difference to the basic example in the react-router docs.

FYI, here is my webpack config:

module.exports = {
    context: resolve(__dirname, 'app'),
    entry: debug ? [
        'react-hot-loader/patch',
        './index.js',
    ] : './index.js',
    output: {
        filename: 'bundle.js',

        path: resolve(__dirname, 'public'),

        publicPath: '/',
        // necessary for HMR to know where to load the hot update chunks
    },

    // possibly change to inline-source-map or something else
    devtool: debug ? 'eval' : false,

    devServer: debug ? {
        hot: true,
        compress: true,
        port: 8080,
        contentBase: resolve(__dirname, 'public'),
        publicPath: '/',
        historyApiFallback: true,
    } : { },
    module: {
        loaders: [
            { test: /\.js$/,
                loaders: [
                    'babel-loader',
                ],
                exclude: /node_modules/,
            },
            {
                test: /\.css$/,
                loaders: [
                    'style-loader',
                    'css-loader?modules',
                    'postcss-loader',
                ],
            },
        ],
    },

...
}
gisderdube
  • 477
  • 1
  • 3
  • 16
  • You'll need to be sure that your server environment knows to forward all requests to the index.html file, this is dependent upon the build environment and server setup. – Toby May 02 '17 at 21:46
  • 1
    You can look into how [create-react-app](https://github.com/facebookincubator/create-react-app) achieves this for more info. – Toby May 02 '17 at 21:48
  • Thank you, but I know that already. In `webpack-dev-server` normally `historyApiFallback` would do that. In node the last route is something like this: `app.use('*', (req, res) => { res.sendFile('index.html') } – gisderdube May 02 '17 at 21:49
  • Does it return 404 on getting index.html or on getting .js/.css files? – GProst May 03 '17 at 06:28
  • @GProst both, the node server as well as the webpack-dev-server return the requested file (e.g. `index.html`, `bundle.js`). I don't have css files, since I'm using `styled-components`, but assets, e.g. images, are being served as expected. – gisderdube May 03 '17 at 09:20

0 Answers0