Search code examples
javascriptreactjsreact-routerreact-router-dom

How to render nested routes in multiple outlets (react router v6.8)


I build a react app with react router 6.8. For my app I have the following structure:

const router = createBrowserRouter(
    createRoutesFromElements(
      <Route path="/" element={<RootLayout />} errorElement={<Error />}>
        <Route path="motive">
          <Route
            path=":motiveSlug"
            element={
              <MotiveSingle />
            }>
            <Route path="artist">
              <Route
                path=":artistSlug"
                element={
                  <ArtistSingle />
                }
              />
            </Route>
          </Route>
        </Route>
      </Route>
    )
  );

This is how I would like to render the Outlets of the elements in :

<div id="configurator">
 {/* Outlet MotiveSingle */}
</div>
<div id="content">
 {/* Outlet ArtistSingle */}
</div>

I want to render the MotiveSingle in #configurator. The Motive details contain the Artist. On click of the Artist Link I want to render the ArtistSingle in #content.

How can I achieve, that MotiveSingle gets rendered in #configurator and ArtistSingle in #content?

Here is a live demo you can inspect: https://codesandbox.io/s/multiple-outlets-in-nested-routes-ckumkk

Here is the Layout for better understanding: enter image description here


Solution

  • You can simplify the routes a bit and achieve what I think you describe with just an additional Motive layout route. The main issue is that each Route component only has one children prop/sets of nested routes, and so they can only be rendered into a single Outlet component. This is fixed my just rendering MotiveSingle directly in a layout route instead of the additional Outlet.

    Example:

    function RootLayout() {
      return (
        <div>
          <nav>
            <ul>
              <li>
                <NavLink to="/">Home</NavLink>
              </li>
              <li>
                <NavLink to="motive/motive-1">Motive 1</NavLink>
              </li>
              <li>
                <NavLink to="motive/motive-2">Motive 2</NavLink>
              </li>
              <li>
                <NavLink to="motive/motive-3">Motive 3</NavLink>
              </li>
            </ul>
          </nav>
    
          <hr />
    
          <main>
            <Outlet />
          </main>
        </div>
      );
    }
    
    const MotiveLayout = () => (
      <>
        <div id="configurator">
          <i>Configurator</i>
          <MotiveSingle />
        </div>
        <hr />
        <div id="content">
          <i>Content</i>
          {/* Outlet for ArtistSingle */}
          <Outlet />
        </div>
      </>
    );
    
    export default function App() {
      const router = createBrowserRouter(
        createRoutesFromElements(
          <Route path="/" element={<RootLayout />} errorElement={<Error />}>
            <Route path="motive/:motiveSlug" element={<MotiveLayout />}>
              <Route path="artist/:artistSlug" element={<ArtistSingle />} />
            </Route>
          </Route>
        )
      );
      return <RouterProvider router={router} />;
    }
    

    Edit how-to-render-nested-routes-in-multiple-outlets-react-router-v6-8

    enter image description here