Nested Routes & Layouts

Master nested routing and layouts in Next.js — how layouts compose, persist across navigation, and enable complex UI architectures without prop drilling.

Last reviewed: January 2025

·Next.js 13Next.js 14Next.js 15
✅
Quick Understanding: Nested routes in Next.js are created by nesting folders inside app/. Each level can have its own layout.tsx that wraps all child routes. Layouts persist across navigation — a sidebar in a layout does not re-mount when you navigate between child pages.

🔍 What Is It?

Nested routes are created by nesting folders in the app/ directory. Each folder can have:

  • →layout.tsx — wraps all child routes, persists across navigation
  • →page.tsx — the content for that exact route
  • →loading.tsx — Suspense fallback for that route level
  • →error.tsx — error boundary for that route level

Layout nesting: When you navigate to /dashboard/settings, Next.js renders:

RootLayout > DashboardLayout > SettingsPage

All layouts in the hierarchy wrap the page. Layouts higher in the tree persist — they do not re-mount on child navigation.

🎯 Why Do We Need It?

In the Pages Router era, implementing a persistent sidebar required complex workarounds: _app.tsx hacks, HOCs, or context. Every page had to manually include the sidebar.

Nested layouts solve this elegantly:

  • →Define the sidebar once in a layout
  • →All child routes automatically get the sidebar
  • →Sidebar state (open/closed, scroll position) persists across navigation
  • →Different sections of the app can have completely different layouts

🏗️ What Happens in Real Projects?

Nested layout architecture for a SaaS app:

app/
├── layout.tsx              # Root: html, body, fonts, analytics
├── (marketing)/
│   ├── layout.tsx          # Marketing: header, footer
│   ├── page.tsx            # Homepage
│   └── pricing/page.tsx    # Pricing page
├── (auth)/
│   ├── layout.tsx          # Auth: centered card layout
│   ├── login/page.tsx
│   └── register/page.tsx
└── (app)/
    ├── layout.tsx          # App: sidebar, topnav, auth guard
    ├── dashboard/page.tsx
    ├── orders/
    │   ├── layout.tsx      # Orders: breadcrumbs, filters
    │   ├── page.tsx        # /orders
    │   └── [id]/page.tsx   # /orders/123
    └── settings/
        ├── layout.tsx      # Settings: sub-navigation tabs
        ├── page.tsx        # /settings
        └── billing/page.tsx # /settings/billing

⚙️ How It Works

Layout rendering and persistence:

  1. User navigates to /dashboard
  2. Next.js renders: RootLayout > AppLayout > DashboardPage
  3. User navigates to /orders
  4. Next.js renders: RootLayout > AppLayout > OrdersLayout > OrdersPage
  5. RootLayout and AppLayout do NOT re-mount — they persist
  6. Only DashboardPage is replaced with OrdersLayout + OrdersPage

This is the key difference from the Pages Router: layouts are part of the React tree and maintain their state (scroll position, open modals, focus) across child navigations.

💻 Example

Nested Layout Architecture — A complete nested layout setup for a SaaS dashboard with auth, sidebar, and sub-navigation.

tsx
import { redirect } from 'next/navigation';
import { getSession } from '@/lib/auth';
import { Sidebar } from '@/components/Sidebar';
import { TopNav } from '@/components/TopNav';

export default async function AppLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  // Auth check in layout — protects all child routes
  const session = await getSession();
  if (!session) redirect('/login');

  return (
    <div className="flex h-screen bg-gray-50">
      <Sidebar user={session.user} />
      <div className="flex flex-col flex-1 overflow-hidden">
        <TopNav user={session.user} />
        <main className="flex-1 overflow-auto p-6">
          {children}
        </main>
      </div>
    </div>
  );
}

🤔 Common Confusions

❓ Can a layout fetch data?

Yes — layouts are Server Components and can be async. They commonly fetch user session, navigation items, or feature flags. Be mindful: layout data fetches run on every navigation to any child route, so keep them fast and cache the results.

❓ How do I share state between a layout and its child pages?

You cannot pass props from layout to page (they are separate React subtrees). Options: (1) React Context in a Client Component provider inside the layout, (2) fetch the same data in both (Next.js deduplicates identical fetches), (3) URL state (searchParams).

❓ What is the difference between layout.tsx and template.tsx?

layout.tsx persists — it does not re-mount on child navigation. template.tsx creates a fresh instance on every navigation. Use layout.tsx for persistent UI (sidebar, nav). Use template.tsx when you need enter/exit animations on every route change.

🚨 Common Production Issues

Auth checks in the wrong layout level — putting auth in a specific route's layout instead of the section's layout means sibling routes are not protected. Put auth in the highest-level layout that covers all protected routes.

Heavy data fetching in root layout — the root layout runs on every request. Fetching slow data here blocks the entire app. Use Suspense or move non-critical data fetching to child layouts.

Layout re-mounting unexpectedly — if you move a page outside its layout's route group, the layout changes and React re-mounts the entire subtree. Plan your route group structure carefully.

✅ Best Practices

Use route groups (folder) to apply different layouts to different app sections

Put auth guards in the section layout, not individual page files

Keep root layout minimal — only fonts, metadata, providers, and analytics

Use loading.tsx at every layout level that fetches data

Avoid heavy computations in layouts — they run on every child navigation

🏛️ Architect's Note

Senior Architect's Perspective

Nested layouts are the most powerful architectural feature of the App Router. The key insight: layouts define the UI contract for a section of your app. The (app) layout says "you must be authenticated and you get a sidebar". The settings layout says "you get sub-navigation". Each layout encapsulates a set of concerns without any child page needing to know about them.

💬 Frequently Asked Questions

Can I have multiple root layouts?

No — there is exactly one root layout (app/layout.tsx) that wraps everything. However, route groups can have their own layouts that are nested inside the root. This gives you the flexibility of multiple layouts without multiple roots.

How do I implement a full-screen page that bypasses the app layout?

Use a route group: put the full-screen page in a separate route group with its own layout (or no layout). Example: (fullscreen)/preview/page.tsx gets its own layout, while (app)/dashboard/page.tsx gets the sidebar layout. The URL /preview and /dashboard are both valid.

Can I conditionally render a layout based on screen size?

Layouts are Server Components — they cannot read screen size (browser API). Use CSS (media queries, Tailwind responsive classes) to show/hide layout elements. For complex responsive layouts, use a Client Component wrapper inside the layout that reads window size.

🎯 Key Takeaways

1Layouts persist across child navigation — they do not re-mount
2Nest layouts to apply different UI shells to different app sections
3Use route groups (folder) to organise layouts without affecting URLs
4Put auth guards in the section layout — not in individual pages
5Layouts are Server Components — they can fetch data directly
6template.tsx re-mounts on every navigation — use for animations

🎯 Practice this topic in interviews

↗ Where this topic fits

Sources

Sources / References

Use these Next.js references to verify the concept in official docs and continue into the most relevant SplashRide pages.

Related SplashRide pages

SplashRide Next.js learning path

Browse the full Next.js topic collection and learning order on SplashRide.

Next.js Interview Prep

Practice Next.js interview questions and scenario-based answers.

Frontend Engineer Career Path

A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.

Full Stack Java Developer Career Path

A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.

Dynamic Routes

Master dynamic routes in Next.js — [slug], [...slug], [[...slug]] patterns, generateStaticParams, and how to handle every routing scenario in production.

Route Groups

Master route groups in Next.js — the parentheses folder pattern that organises your app without affecting URLs, enabling multiple layouts and clean code organisation.