React Router Multiple Layouts - How to Implement Them?
In this post you will learn how to implement inside React Router multiple layouts.
const App = () => {
return (
<div>
<h1>Hello monsterlessons</h1>
<Link to="/">Dashboard</Link>
<Link to="/articles/foo">Article</Link>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/articles/:slug" element={<Article />}></Route>
<Route path="*" element={<NotFound />} />
</Routes>
</div>
);
};
So this is how we typically write routes in React Router. Inside our App
we create links and register our Routes
block. Inside our Routes
we register different Route
with the component that we want to render.
This is how it looks like. We have 2 pages: Dashboard and Article. On the home page by default we render our Dashboard component.
Now the question is how we can use here multiple layouts? Inside our project I already prepared 2 similar components which we will use for Layouts.
// src/pages/Layout1.jsx
const Layout1 = () => {
return (
<div>
<h2>It's layout 1</h2>
</div>
);
};
export default Layout1;
It doesn't have anything special but just an h2
tag inside.
Let's say that we want now to wrap the whole application with our Layout1
.
<Route element={<Layout1/>}>
<Route path="/" element={<Dashboard />} />
<Route path="/articles/:slug" element={<Article />}></Route>
<Route path="*" element={<NotFound />} />
</Route>
We can just wrap all our routes in additional route with Layout1
element.
But as you can see in browser only our Layout1
is rendered. We don't see any content inside. But essentially it still works because all our pages are working but we just don't see the content of nested routes.
It is also important to remember that our Route component for layout doesn't have a path and this is correct.
This is correct because our layout doesn't have any path but only specific route has a path.
But now we must tune our layout so the route content is also rendered.
import { Outlet } from "react-router-dom";
const Layout1 = () => {
return (
<div>
<h2>It's layout 1</h2>
<Outlet />
</div>
);
};
As you can see here we used an Outlet
component from react-router-dom
in order to render our child route. If you used React Router before you might remember that we rendered children
property previously we render our route information. We don't do it anymore and using an Outlet
component is a way to go.
As you can see now on any page we don't just render our layout but also route component.
Now let's do exactly the same in our Layout2
.
// src/pages/Layout2.jsx
import { Outlet } from "react-router-dom";
const Layout2 = () => {
return (
<div>
<h2>It's layout 2</h2>
<Outlet />
</div>
);
};
export default Layout2;
Here we used an Outlet
component just like we did with Layout1
. Now is the question how we can use multiple layouts in our application.
In order to do that we can wrap components in separate layouts.
<Routes>
<Route element={<Layout1 />}>
<Route path="/" element={<Dashboard />} />
</Route>
<Route element={<Layout2 />}>
<Route path="/articles/:slug" element={<Article />}></Route>
</Route>
<Route path="*" element={<NotFound />} />
</Routes>
Here inside of wrapping all our routes in a single layout we create 2 separate groups with Layout1
and Layout2
. It allows us to use multiple layouts across the application.
Which actually means that now we can easily style specific layout for specific set of pages.
const Layout1 = () => {
return (
<div style={{ background: "chocolate" }}>
<h2>It's layout 1</h2>
<Outlet />
</div>
);
};
How example here we used a chocolate background for our Layout1
.
const Layout2 = () => {
return (
<div style={{ background: "teal" }}>
<h2>It's layout 2</h2>
<Outlet />
</div>
);
};
For our Layout2
we provided a background teal.
As you can see now we have differently colored layout on different pages.
Want to conquer your next JavaScript interview? Download my FREE PDF - Pass Your JS Interview with Confidence and start preparing for success today!
📚 Source code of what we've done