By Hemanta Sundaray on 2022-10-14
Lets consider an app that renders two pages: Books & Courses. The Books page is rendered on the /books route & the Courses page is rendered on the /courses route.
Both the pages share a common UI (the navigation bar and padding of p-10), as shown below:
The code for our app looks like the following:
import React from "react"
const Books = () => {
return <h2 className="text-lg font-medium text-gray-600">Books</h2>
}
export default Books
import React from "react";
const Courses = () => {
return <h2 className="text-lg font-medium text-gray-600">Courses</h2>;
};
export default Courses;
import React from "react";
import { Link } from "react-router-dom";
const Navbar = () => {
return (
<nav className="w-full h-20 bg-gray-900">
<ul className="w-40 h-20 p-4 flex justify-between items-center list-none">
<Link to="/books">
<li className="text-gray-50">Books</li>
</Link>
<Link to="/courses">
<li className="text-gray-50">Courses</li>
</Link>
</ul>
</nav>
);
};
export default Navbar;
import React from "react";
import { Routes, Route } from "react-router-dom";
import Navbar from "./components/Navbar";
import Books from "./components/Books";
import Courses from "./components/Courses";
const App = () => {
return (
<>
<Navbar />
<main className="p-10">
<Routes>
<Route path="/books" element={<Books />} />
<Route path="/courses" element={<Courses />} />
</Routes>
</main>
</>
);
};
export default App;
In such scenarios, where multiple routes share a common UI, we can extract the common UI to a layout route.
A layout route is a parent route WITHOUT a path prop. It does not have a path prop because it is not used to render an element when the path pattern matches the current URL. Instead, It is used exclusively to group child routes inside a specific layout.
A route with child routes is called a parent route.
Now that we understand the purpose of a layout route, let’s nest both the /books and /courses routes inside a layout route and extract the common UI inside a new <Layout> component.
Below, we have a <Layout /> component, where we have extracted the <Navbar /> component. We also have a <main> element with a padding of p-10. It represents the main content area of the layout.
import React from "react"
import { Link } from "react-router-dom"
import { Outlet } from "react-router-dom"
const Layout = () => {
return (
<>
<nav className="w-full h-20 bg-gray-900">
<ul className="w-40 h-20 p-4 flex justify-between items-center list-none">
<Link to="/books">
<li className="text-gray-50">Books</li>
</Link>
<Link to="/courses">
<li className="text-gray-50">Courses</li>
</Link>
</ul>
</nav>
<main className="p-10">
<Outlet />
</main>
</>
)
}
export default Layout
Inside the <main> element, we have used the <Outlet /> component to render child components.
Note that an
<Outlet>is used inside a parent route to render the child routes.
In our case, the child components are the /books and /courses routes, which will be rendered inside the <main> element.
The refactored version of the App.js file now looks like this:
import React from "react";
import { Routes, Route } from "react-router-dom";
import Layout from "./components/Layout";
import Books from "./components/Books";
import Courses from "./components/Courses";
const App = () => {
return (
<Routes>
<Route element={<Layout />}>
<Route path="/books" element={<Books />} />
<Route path="/courses" element={<Courses />} />
</Route>
</Routes>
);
};
export default App;
On line 10, we have a layout route (notice, it doesn't have a path prop.) that renders the <Layout> component, which holds the common UI (the navigation bar and padding of p-10).
Note that a layout route doesn't have a path prop as it's not meant to be accessed directly via URLs. It's main purpose is to define the common layout or template for multiple child routes.
I hope you now have a clear understanding of what a layout route is in React Router v6.