Search code examples
javascriptreactjsreact-routerreact-router-dom

ReactRouter v6: Why do nested routes work for some paths but not others resulting in error 404?


I'm currently learning how to use react-router v6. I'm creating nested routes for my App but they don't seem to work and I can't figure out why.

Here is the code from the router:

const router = createBrowserRouter(createRoutesFromElements(
  <Route path="/" element={<Root />}>
    <Route path="about" element={<About />} />
    <Route path="sign-up" element={<SignUp />} />
    <Route path="articles" element={<Articles />} />
    <Route path="articles/:title" element={<Article/>} />
    <Route path="categories" element={<Categories />} />
      <Route path=":name" element={<Category/>} />
    <Route/>
    <Route path="profile" element={<Profile />} />
      <Route path="edit" element={<EditProfileForm />} />
    <Route />
    <Route path="authors/:name" element={<Author />}/>
  </Route>
))

function App() {
  return (
    <>
      <RouterProvider router={router} />
    </>
  );
}

The first nested row of routes (about, sign-up ...) work just fine but when I try to go for "/categories/:name" or "profile/edit" all I get is an error 404, and I can't understand why.

And I bet you guys know why !

I took them off the nested routes and gave them an absolute path and it works, it just won't work as a child route with a relative path

Here is a screen of the app:

app screen in Cayegory nested Route

I'm on the nested route Categories and I want to hit the concepts link which should send me to a page rendering the sub-category but all I get is an error 404 instead:

error 404 when trying to load a nestedRoute within category

Here is a link to a codesandbox with my project running link to codeSandbox.


Solution

  • If you want to nest routes and build the paths up relatively, then the Route components actually need to be nested within a parent Route. You can't just indent a route and expect it to be nested. You are rendering empty Route components instead of opening and closing tags.

    The current code:

    <Route path="categories" element={<Categories />} /> // <-- closed
    <Route path=":name" element={<Category />} />
    <Route /> // <-- empty
    <Route path="profile" element={<Profile />} /> // <-- closed
    <Route path="edit" element={<EditProfileForm />} />
    <Route /> // <-- empty
    

    Should be:

    <Route path="categories" element={<Categories />}> // <-- open tag
      <Route path=":name" element={<Category />} />
    </Route> // <-- closing tag
    <Route path="profile" element={<Profile />}> // <-- open tag
      <Route path="edit" element={<EditProfileForm />} />
    </Route> // <-- closing tag
    

    Full routes example:

    const router = createBrowserRouter(
      createRoutesFromElements(
        <Route path="/" element={<Root />}>
          <Route path="about" element={<About />} />
          <Route path="sign-up" element={<SignUp />} />
          <Route path="articles" element={<Articles />} />
          <Route path="articles/:title" element={<Article />} />
          <Route path="categories" element={<Categories />}>
            <Route path=":name" element={<Category />} />
          </Route>
          <Route path="profile" element={<Profile />}>
            <Route path="edit" element={<EditProfileForm />} />
          </Route>
          <Route path="authors/:name" element={<Author />} />
        </Route>
      )
    );