skip to Main Content

I have the start page in the Root component and I added the Header and Footer components wrapped in a div, but I don’t know how to include them with the rest of the routes in the best way. Am I missing something or using the wrong approach?

Moreover, I am using createBrowserRouter instead of BrowserRouter since I am using data APIs as mentioned in the docs Picking a Router

Here is my code:

const router = createBrowserRouter([
  {
    path: '/',
    element: (
      <div>
        <Header />
        <Root />
        <Footer />
      </div>
    ),
    errorElement: <ErrorPage />,
  },
  {
    path: '/products',
    element: <ProductsList />,
  },
  {
    path: '/products/:productId',
    element: <SingleProductPage />,
  },
])

const root = ReactDOM.createRoot(document.getElementById('app'))
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <RouterProvider router={router} />
    </Provider>
  </React.StrictMode>

When I navigate to ‘/’ the Header and Footer displays, but that’s not the case for other routes.

2

Answers


  1. The reason you have the header and footer displaying always is because it’s included in the route. In your case, keep the createBrowserRouter away from <Header> and <Footer>. Use a layout or something similar.

    If you’re using RouterProvider v6.9.0 – React Router, then what you can do is, have a layout component:

    const Layout = ({children}) => (
      <Header />
      {children}
      <Footer />
    );
    

    And use it this way:

    const router = createBrowserRouter([
      {
        path: '/',
        element: (
          <Layout>
            <Root />
          </Layout>
        ),
        errorElement: <ErrorPage /></Layout>,
      },
      {
        path: '/products',
        element: <Layout><ProductsList /></Layout>,
      },
      {
        path: '/products/:productId',
        element: <Layout><SingleProductPage /></Layout>,
      },
    ]);
    

    This is the most easiest method. You can also add this element here and send the path as children of that element:

    const router = createBrowserRouter([
      {
        element: <Layout />,
        children: [
          {
            path: "/",
            element: <Root />,
          },
          {
            path: "/products",
            element: <ProductsList />
          },
          {
            path: "/products/:productId",
            element: <SingleProductPage />
          }
        ]
      }
    ]);
    
    Login or Signup to reply.
  2. React Router has a concept of Layout Routes
    Basically it’s a route without any path which doesn’t participate in the URL matching.

    It only exists to make wrapping multiple child routes in the same layout simpler

    In your example, you can declare a layout route like this :

    import { Outlet } from "react-router-dom";
    
    function Layout() {
      return (
          <>
            <Header />
            <Outlet />
            <Footer />
          </>
      );
    }
    
    const router = createBrowserRouter([
      {
        element: <Layout/>,
        errorElement: <ErrorPage />,
        children: [  
          {
            path: '/',
            element: <Root />
          },
          {
            path: '/products',
            element: <ProductsList />
          },
          {
            path: '/products/:productId',
            element: <SingleProductPage />
          }
        ]
      }
    ])
    

    Notice the presence of <Outlet /> in the Layout component to display the child route.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search