Search code examples
reactjsreact-router-dom

Nested routes do not work (react router v6)


after browsing for a while on the internet I could not figure out why my nested routes do not work.

index.js
<BrowserRouter>
   12             <Navbar />
   13             <App />
   14         </BrowserRouter>


   App.js
   <>
   <Routes>
                   <Route path="/" element={<Home />}>
                      <Route path="auth" element={<AuthApp />} />
                   </Route>
    </Routes>
    <Outlet />
   </>


      authApp.js
    6 const AuthApp = () => {
    7     return (
    8         <>
    9             <Routes>
   10                 <Route path="login" element={<LoginRoute />} />
   11                 <Route path="register" element={<RegisterRoute />} />
   12             </Routes>
   13             <Outlet />
   14         </>
   15     );
>> 16 }

LoginRoute, Home and RegisterRoute are very simple elements that for now should just display an h1. The problem is that /auth/login and /auth/register do not work. The links should be correct (I also tried manually to enter the url)

<nav style={navStyle}>
               <CustomNavLink to="/" routeName="Home" />
               <CustomNavLink to="/auth/login" routeName="Login" />
               <CustomNavLink to="/auth/register" routeName="Register" />
</nav>

Could someone spot the problem? Thank you in advance. Additional question: Everytime I hit the login and register links I seem to get two hits. This is the output I see in the console:

No routes matched location "/auth/login" 
No routes matched location "/auth/login" 

Could someone explain this as well?


Solution

  • The issue is because nested routes are not the same thing as descendent routes.

    Nested Routes:

    Nested routes are Route components directly nested in another Route component. The parent Route component's element component needs to render an Outlet for the nested routes to render their element content into for display when matched.

    App

    <Route path="/" element={<Home />}>
      <Route path="auth" element={<AuthApp />} />
    </Route>
    

    Descendent Routes:

    Descendent routes are routes that are rendered by some descendent component. These necessarily need to be rendered into a Routes component to handle further route matching and rendering.

    AuthApp

    const AuthApp = () => {
      return (
        <>
          <Routes>
            <Route path="login" element={<LoginRoute />} />
            <Route path="register" element={<RegisterRoute />} />
          </Routes>
          <Outlet />
        </>
      );
    }
    

    In order for descendent routes to be able to still be matched the parent route needs to specify the trailing wildcard "*" matcher to its path. In this case, it is the "/auth" path. Update the parent route to "/auth/*" to allow descendent routes to also be matched and rendered.

    <Route path="/" element={<Home />}>
      <Route path="auth/*" element={<AuthApp />} />
    </Route>
    

    For more information see How do I nest routes deep in the tree