Facebook Pixel

Nested Layouts & Routes

In this tutorial, we will learn how to use nested layouts and nested routes with React Router 7 in a React 19 application. Nested routing is essential for building real world apps where different sections share UI but still have independent pages.

This guide is beginner friendly and uses only modern React 19 and React Router 7 patterns.


What We Will Learn

  • What nested layouts are
  • Why nested routes are useful
  • How <Outlet /> works
  • Creating a root layout
  • Creating section specific layouts
  • Structuring nested routes cleanly

What Are Nested Layouts

A layout is a component that wraps other routes and provides shared UI.

Examples of shared UI:

  • Navigation bars
  • Sidebars
  • Footers
  • Dashboards

Nested layouts allow you to:

  • Share UI across related pages
  • Avoid repeating markup
  • Keep route logic organized

Each layout renders an <Outlet />, which is where child routes appear.


Basic Folder Structure

We will build a small app with a public area and a dashboard area.

/src
  /app
    app.tsx
    root-layout.tsx
    dashboard-layout.tsx
  /pages
    home.tsx
    about.tsx
    /dashboard
      overview.tsx
      settings.tsx
  main.tsx

Root Layout

The root layout wraps the entire application.

root-layout.tsx

// src/app/root-layout.tsx
import { Outlet, Link } from "react-router";
 
export default function RootLayout() {
  return (
    <>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/dashboard">Dashboard</Link>
      </nav>
 
      <main>
        <Outlet />
      </main>
    </>
  );
}

<Outlet /> is where child routes will render.


Dashboard Layout

The dashboard layout is nested inside the root layout and only applies to dashboard routes.

dashboard-layout.tsx

// src/app/dashboard-layout.tsx
import { Outlet, Link } from "react-router";
 
export default function DashboardLayout() {
  return (
    <section>
      <aside>
        <Link to="/dashboard">Overview</Link>
        <Link to="/dashboard/settings">Settings</Link>
      </aside>
 
      <div>
        <Outlet />
      </div>
    </section>
  );
}

This layout adds a sidebar that only appears on dashboard pages.


Creating Pages

Home Page

// src/pages/home.tsx
export default function Home() {
  return (
    <>
      <title>Home</title>
      <meta name="description" content="Home page" />
 
      <h1>Home</h1>
      <p>Public landing page</p>
    </>
  );
}

About Page

// src/pages/about.tsx
export default function About() {
  return (
    <>
      <title>About</title>
      <meta name="description" content="About page" />
 
      <h1>About</h1>
      <p>About this application</p>
    </>
  );
}

Dashboard Overview

// src/pages/dashboard/overview.tsx
export default function Overview() {
  return (
    <>
      <title>Dashboard Overview</title>
      <h1>Overview</h1>
      <p>Dashboard summary</p>
    </>
  );
}

Dashboard Settings

// src/pages/dashboard/settings.tsx
export default function Settings() {
  return (
    <>
      <title>Dashboard Settings</title>
      <h1>Settings</h1>
      <p>Manage your preferences</p>
    </>
  );
}

Defining Nested Routes

Now we connect everything in the router configuration.

app.tsx

// src/app/app.tsx
import { createBrowserRouter } from "react-router";
import RootLayout from "./root-layout";
import DashboardLayout from "./dashboard-layout";
 
import Home from "../pages/home";
import About from "../pages/about";
import Overview from "../pages/dashboard/overview";
import Settings from "../pages/dashboard/settings";
 
export const router = createBrowserRouter([
  {
    element: <RootLayout />,
    children: [
      { path: "/", element: <Home /> },
      { path: "/about", element: <About /> },
      {
        path: "/dashboard",
        element: <DashboardLayout />,
        children: [
          { index: true, element: <Overview /> },
          { path: "settings", element: <Settings /> },
        ],
      },
    ],
  },
]);

Understanding How Nesting Works

  • RootLayout always renders
  • DashboardLayout only renders for /dashboard routes
  • <Outlet /> controls where child routes appear
  • Nested paths are relative to their parent

index: true means the default child route.


Why Nested Layouts Matter

Nested layouts allow you to:

  • Keep UI consistent
  • Reduce duplication
  • Scale routing without chaos
  • Match app structure to URL structure

This mirrors how users mentally organize your app.


Best Practices

  • One layout per logical section
  • Keep layouts focused on structure, not logic
  • Avoid deeply nested routes unless necessary
  • Use index routes for default views
  • Name layouts clearly

Conclusion

Nested layouts and routes are a core concept in React Router 7. They allow you to build complex applications while keeping your codebase clean, predictable, and scalable.

Once you understand <Outlet /> and route nesting, structuring large applications becomes straightforward and intuitive.