When building real-world applications, some UI parts remain the same across multiple pages, such as:

  1. Header
  2. Navbar
  3. Footer
  4. Sidebar

Instead of repeating this code on every page, Next.js provides a powerful feature called Layouts.

Layouts help you create shared UI structures that wrap multiple pages automatically.

Nested layouts allow you to create different layouts for different sections of your application.


What are Layouts in Next.js?

A layout is a React component that wraps pages and persists across page navigation. Instead of duplicating common UI elements like headers, footers, and sidebars on every page, layouts provide a reusable structure that automatically wraps your page content.

Layout File Structure

Layouts are defined using a special file named layout.tsx (or layout.js):


app/
  ├─ layout.tsx          (Root layout)
  ├─ page.tsx
  ├─ dashboard/
  │   ├─ layout.tsx      (Nested layout)
  │   └─ page.tsx

Key Benefits of Layouts

  • Code Reusability: Define common UI components once and use them across multiple pages
  • Shared State: Maintain state that persists across page navigation
  • Performance: Avoid re-rendering shared UI when navigating between pages
  • Maintainability: Centralize shared UI logic in one place

Common Layout Components

Typical elements that go in layouts include:

  • Navigation bars and menus
  • Headers and footers
  • Sidebars and drawer navigation
  • Authentication wrappers
  • Analytics providers

Root Layout in App Router

The root layout is the main layout of your entire application. Every route in your application will be wrapped by this layout.

Location of Root Layout

The root layout is defined at the top level of the app/ directory with a file named layout.tsx. This is a required file for Next.js 13+ with App Router.

Root Layout Example

// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <title>My App</title>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
      </head>
      <body>
        <header>
          <h1>My Application Header</h1>
        </header>
        <nav>
          <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/about">About</a></li>
            <li><a href="/contact">Contact</a></li>
          </ul>
        </nav>
        <main>
          {children}
        </main>
        <footer>
          <p>&copy; 2026 My Application</p>
        </footer>
      </body>
    </html>
  );
}

Key Characteristics of Root Layout

  • Required file: Every Next.js App Router application must have a root layout.
  • Must include <html> and <body> tags: Unlike other layouts, the root layout must define the HTML document structure.
  • Wraps all routes: The root layout wraps all pages and nested layouts in your application.
  • Single instance: There is only one root layout per application.

Nested Layouts and Layout Composition

Nested layouts allow you to create segment-specific layouts for different sections of your application. Each subdirectory in the app/ directory can have its own layout.tsx file.

When to Use Nested Layouts

Create nested layouts for different sections that need distinct UI structures:

  • Marketing site layout: Header, hero section, footer
  • Dashboard layout: Sidebar navigation, top bar, main content
  • Admin layout: Admin controls, user management, settings
  • Auth layout: Login form with minimal UI

Nested Layouts File Structure


app/
  ├─ layout.tsx                 (Root layout - wraps everything)
  ├─ page.tsx
  ├─ about/
  │   └─ page.tsx              (Uses root layout)
  ├─ dashboard/
  │   ├─ layout.tsx            (Nested layout - wraps dashboard pages)
  │   ├─ page.tsx
  │   ├─ settings/
  │   │   └─ page.tsx          (Uses both root and dashboard layouts)
  │   └─ profile/
  │       └─ page.tsx          (Uses both root and dashboard layouts)
  └─ auth/
      ├─ layout.tsx            (Different layout for auth section)
      ├─ login/
      │   └─ page.tsx
      └─ register/
          └─ page.tsx

Root Layout Example


// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <title>My App</title>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
      </head>
      <body>
        <header>
          <h1>My Application</h1>
        </header>
        <nav>
          <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/about">About</a></li>
            <li><a href="/dashboard">Dashboard</a></li>
          </ul>        
        </nav>
        <main>
          {children}
        </main>
        <footer>
          <p>© 2026 My Application</p>
        </footer>
      </body>
    </html>
  );
}

Nested Dashboard Layout Example

This layout only applies to pages within the /dashboard route and its sub-routes:


// app/dashboard/layout.tsx
import Sidebar from '@/components/Sidebar';

export default function DashboardLayout({ children }: { children: React.ReactNode }) {
  return (
    <div className="dashboard-container">
      <Sidebar />
      <main className="dashboard-main">
        <div className="dashboard-header">
          <h1>Dashboard</h1>
        </div>
        {children}
      </main>
    </div>
  );
}

Layout Composition and Nesting Order

Layouts automatically nest and compose. When navigating to /dashboard/settings, the component tree looks like this:


<RootLayout>                    {/* app/layout.tsx */}
  <header>Header</header>
  <nav>Navigation</nav>
  <main>
    <DashboardLayout>           {/* app/dashboard/layout.tsx */}
      <Sidebar />
      <div className="dashboard-header">Dashboard</div>
      <SettingsPage />           {/* app/dashboard/settings/page.tsx */}
    </DashboardLayout>
  </main>
  <footer>Footer</footer>
</RootLayout>

Key Points About Nested Layouts

  • Auto Composition: Child layouts automatically wrap parent layouts. You don't need to manually compose them.
  • Preserve State: Shared state in parent layouts persists when navigating between sibling routes.
  • Route-Specific: A layout only applies to routes within its directory and its subdirectories.
  • Required Children Prop: Every layout must accept and render the children prop.