Skip to content

Routing not working in a react app with webpack

I’m trying to create a react app with webpack which has some routing as well.

 "react-router-dom": "^5.2.0",

The routing works but when I go to a specific route and reload the page, it gives an error cannot get /about

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";

export default function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/users">Users</Link>
            </li>
          </ul>
        </nav>
        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/users">
            <Users />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}

As mentioned in this answer, adding

devServer: {
    historyApiFallback: true,
  }

fixes the issue when its being run locally, but as soon as I deploy it, I get the same error

Answer

This happens because your server does not know what to do when it is hit by the /about route, initially when the browser has no asset files (HTML, JS, etc.). It occurs only when you are at /about and you refresh the page.

React router is a client side router, and hence the browser needs to load the client assets completely before it can work on your routes.

All you need to do is to configure your server to give all your assets to client even if it hit by an unknown route. i.e. when the 404 (Not found) situation arises at the server, your server should still provide all the assets that would otherwise be delivered when the route is at /.

And your react router should handle the 404 (Not found) event at the client side. as follows,

<Router>
  <div>
    <nav>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/users">Users</Link>
        </li>
      </ul>
    </nav>
    <Switch>
      <Route exact path="/about">
        <About />
      </Route>
      <Route exact path="/users">
        <Users />
      </Route>
      <Route exact path="/">
        <Home />
      </Route>
      <Route path="*">
        <h2>Page Not Found</h2>
      </Route>
    </Switch>
  </div>
</Router>

Please remember that, if you want to nest the routes then remove the exact property from the parent Route.