0

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;
2
  • 1
    How are you building, and serving/hosting, this React app? Can you edit to clarify? See minimal reproducible example. The basic gist is that the root index.html file should be returned for all page requests into application. Can you share also your index.html and index.js files, and any other files you think may be relevant?
    – Drew Reese
    Commented Sep 6, 2023 at 16:07
  • @DrewReese I've created as small of a reproducible example as I can and updated the question Commented Sep 8, 2023 at 10:29

0