Search code examples
javascriptreactjsreact-routerreact-router-dom

Error component route is rendering below every other component route


In my code below the Error page is rendering together with every other component.
I would like the Error page to render only when the url is wrongly typed and another component cannot be rendered:

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Routes,
} from "react-router-dom";
import { Navbar, Sidebar, Footer } from "./components";
import {
  Home,
  SingleProduct,
  Cart,
  Checkout,
  Error,
  About,
  Products,
  PrivateRoute,
} from "./pages";

function App() {
  return (
    <Router>
      <Navbar />
      <Sidebar />
      <Routes>
        <Route exact path="/" element={<Home />} />
      </Routes>
      <Routes>
        <Route exact path="/about" element={<About />} />
      </Routes>
      <Routes>
        <Route exact path="/cart" element={<Cart />} />
      </Routes>
      <Routes>
        <Route exact path="products">
          <Route index element={<Products />} />
          <Route exact path=":productId" element={<SingleProduct />} />
        </Route>
      </Routes>
      <Routes>
        <Route exact path="/checkout" element={<Checkout />} />
      </Routes>
      <Routes>
        <Route path="*" element={<Error />} />
      </Routes>
      <Footer />
    </Router>
  );
}

export default App;

I am expecting the error page to load on wrongly typed URLs and it's working, but it also renders in every single url below my other components.


Solution

  • As long as any other route is matched and rendered within a single Routes component, the "catch-all" Error route and component won't be rendered.

    Change your router to this:

    <Router>
      <Navbar />
      <Sidebar />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/cart" element={<Cart />} />
        <Route path="products">
          <Route index element={<Products />} />
          <Route path=":productId" element={<SingleProduct />} />
        </Route>
        <Route path="/checkout" element={<Checkout />} />
        <Route path="*" element={<Error />} />
      </Routes>
      <Footer />
    </Router>