user697576
user697576

Reputation: 827

How to template jsx with createBrowserRouter

From my understanding:

  1. <Route loader...> "only works if using a data router"
  2. data routers (like createBrowserRouter) don't allow for wrapping 'all' of the routes in jsx containing <Link> components. See examples

Example: Non data routers

<Router>
  <header>
    <Link to="/">Home</Link>
  </header>
  <Routes>
    <Route...>
    <Route...>
  </Routes>
</Router>

Example: data routers (throws error) full example

const router = createBrowserRouter([....]);
<div>
  <header>
    <Link to="/">Home</Link>
  </header>
  <RouterProvider router={router} />
</div>

My question is this: How can we create a template that wraps the RouterProvider (and all the content it imports) with a template that makes use of <Link> functionality?

Upvotes: 10

Views: 21513

Answers (2)

MadaShindeInai
MadaShindeInai

Reputation: 590

React Router examples offer a little bit another way to build routes structure.

let routes: RouteObject[] = [
{
  path: "/",
  element: <Layout />,
  children: [
    { index: true, element: <Home /> },
    {
      path: "/courses",
      element: <Courses />,
      children: [
        { index: true, element: <CoursesIndex /> },
        { path: "/courses/:id", element: <Course /> },
      ],
    },
    { path: "*", element: <NoMatch /> },
  ],
},
];  

https://stackblitz.com/github/remix-run/react-router/tree/main/examples/route-objects?file=src%2FApp.tsx

Upvotes: 4

Drew Reese
Drew Reese

Reputation: 203373

Render the header/Navbar component as part of the routing configuration. In this case you'll create a layout route that renders the header and navbar, and an Outlet for nested routes to render their content into.

Example:

export const Navbar = () => {
  return (
    <div>
      <Link to='/'>Home</Link>
      <Link to='/foo'>Foo</Link>
      <Link to='/bar'>Bar</Link>
    </div>
  );
};

...

import {
  createBrowserRouter,
  RouterProvider,
  Outlet
} from 'react-router-dom';

const HeaderLayout = () => (
  <>
    <header>
      <Navbar />
    </header>
    <Outlet />
  </>
);

const router = createBrowserRouter([
  {
    element: <HeaderLayout />,
    children: [
      {
        path: "/",
        element: <div>Hello</div>,
      },
      {
        path: '/foo',
        element: <div>foo</div>,
      },
      {
        path: '/bar',
        element: <div>foo</div>,
      }
    ],
  },
]);

export function App(props) {
  return (
    <div className='App'>
      <RouterProvider router={router} />
    </div>
  );
}

Upvotes: 33

Related Questions