Nested Routes & Outlet Layouts
Build multi-level route layouts using nested and the component.
Nested Routes & Outlet Layouts is a free React Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Are Nested Routes?
Nested routes in React Router v6 let you compose layouts: a parent route renders a shell (nav, sidebar) and child routes fill in the content area via <Outlet />.
Defining Nested Routes
Place child <Route> elements inside a parent <Route> in your router configuration. The parent path is a prefix for all children.
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const router = createBrowserRouter([
{
path: '/',
element: <RootLayout />,
children: [
{ path: 'dashboard', element: <Dashboard /> },
{ path: 'settings', element: <Settings /> },
],
},
]);The Outlet Component
<Outlet /> is a placeholder in the parent layout component. React Router swaps it with the matched child route's element.
function RootLayout() {
return (
<div>
<nav>
<Link to="/dashboard">Dashboard</Link>
<Link to="/settings">Settings</Link>
</nav>
<main>
<Outlet /> {/* child route renders here */}
</main>
</div>
);
}Index Routes
An index: true route renders when the parent URL matches exactly, acting as the default child when no other child path matches.
{
path: '/',
element: <RootLayout />,
children: [
{ index: true, element: <Home /> }, // renders at '/'
{ path: 'about', element: <About /> },
],
}Multi-Level Nesting
Routes can nest multiple levels deep. Each layout component in the chain renders an <Outlet /> for its own children.
const router = createBrowserRouter([
{
path: '/app',
element: <AppShell />,
children: [
{
path: 'users',
element: <UsersLayout />,
children: [
{ index: true, element: <UserList /> },
{ path: ':id', element: <UserDetail /> },
],
},
],
},
]);Outlet Context
Pass data from a layout to nested child routes via the context prop on <Outlet /> and read it with useOutletContext() in children.
// Parent layout
function UsersLayout() {
const [selected, setSelected] = useState(null);
return <Outlet context={{ selected, setSelected }} />;
}
// Child route
function UserDetail() {
const { selected } = useOutletContext();
return <div>{selected}</div>;
}Named Layouts with Pathless Routes
A route without a path wraps children for layout only, without adding a URL segment. Useful for grouping routes under a shared layout.
{
element: <AuthenticatedLayout />, // no path
children: [
{ path: '/profile', element: <Profile /> },
{ path: '/billing', element: <Billing /> },
],
}Relative Links in Nested Routes
Inside a nested route, <Link to='sibling'> resolves relative to the current route's path, just like relative URLs in HTML.
// Inside /app/users — link goes to /app/users/new
function UserList() {
return <Link to="new">Add User</Link>;
}useMatch in Nested Routes
useMatch(pattern) returns match data when the current URL matches the pattern, useful for styling active links in nested layouts.
function NavLink({ to, children }) {
const match = useMatch(to);
return (
<Link to={to} className={match ? 'active' : ''}>
{children}
</Link>
);
}Error Boundaries per Segment
Add an errorElement to any nested route to catch errors only in that segment without crashing the entire layout shell.
{
path: 'users',
element: <UsersLayout />,
errorElement: <UsersError />,
children: [
{ path: ':id', element: <UserDetail /> },
],
}Practical Pattern: Dashboard Layout
A typical dashboard uses a top-level route for the app shell (header + sidebar) with nested routes for each section, keeping the shell mounted while only the content area changes.
function DashboardShell() {
return (
<div className="dashboard">
<Sidebar />
<div className="content">
<Outlet />
</div>
</div>
);
}Quick Check
Which component must a parent layout render to display its matched child route?
Recap
Nested routes let parent routes render persistent layouts while child routes fill the <Outlet />. Use index routes for default children, pathless routes for shared layouts, and useOutletContext to pass data down.
Frequently asked questions
Is the “Nested Routes & Outlet Layouts” lesson free?
Yes — the full text of “Nested Routes & Outlet Layouts” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.
What will I learn in “Nested Routes & Outlet Layouts”?
Build multi-level route layouts using nested and the component. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start React Academy?
No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Nested Routes & Outlet Layouts” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this React Academy lesson?
Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Nested Routes & Outlet Layouts
- Loaders & Actions (Data Router API)
- Protected Routes & Auth Guards
- Managing State in URL Search Params