React router allows react apps to handle /arbitrary/route
. In order this to work, I need my server to send the React app on any matched route.
But webpa
I agree with the majority of existing answers.
One key thing I wanted to mention is if you hit issues when manually reloading pages on deeper paths where it keeps the all but the last section of the path and tacks on the name of your js
bundle file you probably need an extra setting (specifically the publicPath
setting).
For example, if I have a path /foo/bar
and my bundler file is called bundle.js
. When I try to manually refresh the page I get a 404 saying /foo/bundle.js
cannot be found. Interestingly if you try reloading from the path /foo
you see no issues (this is because the fallback handles it).
Try using the below in conjunction with your existing webpack
config to fix the issue. output.publicPath
is the key piece!
output: {
filename: 'bundle.js',
publicPath: '/',
path: path.resolve(__dirname, 'public')
},
...
devServer: {
historyApiFallback: true
}
You can enable historyApiFallback to serve the index.html
instead of an 404 error when no other resource has been found at this location.
let devServer = new WebpackDevServer(compiler, {
historyApiFallback: true,
});
If you want to serve different files for different URIs, you can add basic rewriting rules to this option. The index.html
will still be served for other paths.
let devServer = new WebpackDevServer(compiler, {
historyApiFallback: {
rewrites: [
{ from: /^\/page1/, to: '/page1.html' },
{ from: /^\/page2/, to: '/page2.html' },
{ from: /^\/page3/, to: '/page3.html' },
]
},
});
For me I had dots "." in my path e.g. /orgs.csv
so I had to put this in my webpack confg.
devServer: {
historyApiFallback: {
disableDotRule: true,
},
},
Adding public path to config helps webpack to understand real root (/
) even when you are on subroutes, eg. /article/uuid
So modify your webpack config and add following:
output: {
publicPath: "/"
}
devServer: {
historyApiFallback: true
}
Without publicPath
resources might not be loaded properly, only index.html.
Tested on Webpack 4.6
Larger part of config (just to have better picture):
entry: "./main.js",
output: {
publicPath: "/",
path: path.join(__dirname, "public"),
filename: "bundle-[hash].js"
},
devServer: {
host: "domain.local",
https: true,
port: 123,
hot: true,
contentBase: "./public",
inline: true,
disableHostCheck: true,
historyApiFallback: true
}