I have a simple React Route set up with Nested Routes using react-router-dom
<Link to={"/"} replace={false}>Home</Link>
<Link to={"/routeA/pageA"} replace={false}>Page A</Link>
<Link to={"/routeB/pageB"} replace={false}>Page B</Link>
<Routes>
<Route path="/" element={<p>Home</p>} />
<Route path="/routeA">
<Route index element={<p>Not Found</p>} />
<Route path="pageA" element={<p>Page A</p>} />
</Route>
<Route path="/routeB">
<Route index element={<p>Not Found</p>} />
<Route path="pageB" element={<p>Page B</p>} />
</Route>
<Route path="*" element={<p>Not Found</p>} />
</Routes>
That is being run with the webpack dev server and these settings
module.exports = {
...
devServer: {
port: "31",
static: {
directory: path.join(__dirname, "public")
},
open: true,
hot: true,
liveReload: true,
historyApiFallback: true
},
...
};
The routes seem to be working fine when being accessed with the links and using the browser "Back" button it seems to be working fine as well, but when trying to use the URLs in the search bar manually it doesn't seem to work right.
When only using the top level Routes it seems to work fine
http://siteurl:31/ : shows Home (correct)
http://siteurl:31/routeA : shows Not Found (correct)
http://siteurl:31/routeB : shows Not Found (correct)
But when trying to use the nested Routes
http://siteurl:31/routeA/pageA : crashes
http://siteurl:31/routeA/anything : crashes
http://siteurl:31/routeB/pageB : crashes
http://siteurl:31/routeB/anything : crashes
With the error
GET http://siteurl:31/setup/index_bundle.js 404 (Not Found)
Full code:
package.json
{
"name": "Example",
"version": "0.0.1",
"description": "Example",
"main": "./index.js",
"scripts": {
"start": "webpack-dev-server .",
"bundle": "webpack ."
},
"repository": {
"type": "git",
"url": "none"
},
"keywords": [
"none"
],
"author": "Dev User",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.22.15",
"@babel/core": "^7.22.15",
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.22.15",
"@babel/preset-react": "^7.22.15",
"babel-loader": "^9.1.3",
"html-webpack-plugin": "^5.5.3",
"path": "^0.12.7",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0"
}
}
webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
mode: "development",
entry: "./index.js",
output: {
path: path.resolve(__dirname, "./dist"),
filename: "index_bundle.js"
},
target: "web",
devServer: {
port: "31",
static: { directory: path.join(__dirname, "public") },
open: true,
hot: true,
liveReload: true,
historyApiFallback: true,
allowedHosts: "all"
},
resolve: { extensions: [".js", ".jsx", ".json"] },
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: { presets: ["@babel/preset-env", "@babel/preset-react"] }
}
}
],
},
plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname, "public", "index.html") }) ]
};
index.js
import React from "react";
import {createRoot} from "react-dom/client";
import App from "./src/App.js";
const container = document.getElementById("root");
const root = createRoot(container);
root.render(<App/>);
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
src/App.js
import React from "react";
import {BrowserRouter, Link, Routes, Route, Outlet} from "react-router-dom";
const App = () => {
return(
<BrowserRouter>
<Link to={"/"} replace={false}>Home</Link>
<Link to={"/routeA/pageA"} replace={false}>Page A</Link>
<Link to={"/routeB/pageB"} replace={false}>Page B</Link>
<Routes>
<Route path="/" element={<p>Home</p>} />
<Route path="/routeA">
<Route index element={<p>Not Found</p>} />
<Route path="pageA" element={<p>Page A</p>} />
</Route>
<Route path="/routeB">
<Route index element={<p>Not Found</p>} />
<Route path="pageB" element={<p>Page B</p>} />
</Route>
<Route path="*" element={<p>Not Found</p>} />
</Routes>
</BrowserRouter>
);
}
export default App;