React + Webpack: can't redirect all my routes to index.html

I'm building a React application without using create-react-app, but using webpack to build it and webpack-dev-server to serve it.

My directory structure is:

myApp
|
|---docs/
|   |
|   |---dist/
|   |   |
|   |   |---bundle.js
|   |---index.html
|---src/
|---package.json
|---package-lock.json
|---README.md
|---webpack.config.js

and my webpack.config.js is:

module.exports = {
  entry: __dirname + '/src/index.js',
  output: {
    filename: 'bundle.js',
    path: __dirname + '/docs/dist'
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      },
      {
        test: [/.css$|.scss$/],
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      },
      {
        test: /\.(jpg|jpeg|png|jpg|gif)$/,
        loader: 'file-loader?limit=10000&name=../assets/images/[name].[ext]'
      },
      {
        test: /\.(woff|woff2|eot|ttf|svg)$/,
        loader: 'url-loader?limit=100000&name=../assets/fonts/[name].[ext]'
      }
    ]
  },
  resolve: {
    extensions: ['*', '.js', '.jsx']
  },
  devServer: {
    contentBase: './docs',
    compress: true,
    port: 9000,
    historyApiFallback: true
  }
};

The Webpack documentation about historyApiFallback says this configuration historyApiFallback: true will redirect all 404 responses to index.html.

It happens that I am using react-router-dom and I have the following routes:

<BrowserRouter>
    <Switch>
        <Route exact path="/" component={Homepage} />
        <Route path="/about" component={About} />
        <Route path="/article/:id/show" component={Article} />
        <Route path="/donate" component={Donate} />
    </Switch>
</BrowserRouter>

Everything is fine with /, /about and /donate, but when I try the route /article/<something>/show I still get a 404 error message, as the image below shows.

enter image description here

It says it can't find the bundle.jsfile. But then, it is not redirecting my route to index.html in the first place. If it were doing so, it would find the bundle.jsfile, as it does in the other routes.

How may I do this work?

EDIT

Setting publicPath to /, as suggested, won't solve the problem. First of all, / is not my asset's path.

Setting it /docs/dist, my real public asset's path, work to some extent. But the solution comes only if you use an absolute path when loading the resources.

Upvotes: 2

Views: 2600

Answers (1)

Chukwuemeka Inya
Chukwuemeka Inya

Reputation: 2671

You need to specify the publicPath in the output object like so:

    output: {
        filename: 'bundle.js',
        path: __dirname + '/docs/dist',
        publicPath: '/'
    },

You can read the doc for more insight.

Upvotes: 2

Related Questions