Skip to content

Nested Routes

Nested routes let you build multi-level URL structures — like /dashboard/settings/profile — where each level can contribute its own layout, loading state, and error boundary. This lesson covers how nesting composes in the App Router.

How Nesting Composes Layouts and Pages

Every folder level between app/ and a page.tsx file can optionally include its own layout.tsx. When you visit a deeply nested route, Next.js renders every matching layout from the root down to the page, wrapping each one inside the layout above it — this is why layouts are described as composing.

Because each level's layout only re-renders when something inside it actually changes, navigating between two routes that share a parent layout (like /dashboard/settings and /dashboard/profile, both under a shared /dashboard layout) preserves that shared layout's state instead of remounting it.

app/
  dashboard/
    layout.tsx        // wraps everything under /dashboard
    page.tsx           // /dashboard
    settings/
      layout.tsx        // wraps everything under /dashboard/settings
      page.tsx           // /dashboard/settings
      profile/
        page.tsx          // /dashboard/settings/profile

Visiting /dashboard/settings/profile renders the root layout, the dashboard layout, the settings layout, and finally the profile page — all nested inside each other.

Nesting Rules to Remember

app/
  layout.tsx     // always renders (root layout)
  a/
    layout.tsx   // renders for every route under /a
    page.tsx     // /a
    b/
      page.tsx   // /a/b (still wrapped by /a's layout, since /a/b has no own layout)
  • A layout.tsx is optional at every level; if a level has none, the parent's layout keeps applying.
  • Layouts nest in file-system order: root layout first, then each folder's layout, innermost last.
  • A layout's children prop is where the next nested layout or the final page renders.
  • Layouts persist across navigations between sibling routes that share them — they do not remount.

Nested Routes Cheat Sheet

How deeply nested URLs map to composed layouts.

URL Layouts Rendered (outer → inner)
/dashboard Root layout → Dashboard layout
/dashboard/settings Root layout → Dashboard layout → Settings layout
/dashboard/settings/profile Root → Dashboard → Settings (no own layout, reused)

Why Shared Layouts Preserve State

When you navigate from /dashboard/settings to /dashboard/profile, both routes share the same /dashboard layout instance. Because Next.js only remounts the parts of the tree that actually change, any state inside that shared layout — like a sidebar's scroll position or an open/closed menu — survives the navigation.

  • Shared layouts are not re-fetched or remounted on navigation between sibling routes.
  • Only the segment that actually differs (the page, or a deeper nested layout) re-renders.
  • This is a deliberate performance and UX optimization, not something you need to configure.

Linking Between Nested Routes

Use the <Link> component (covered in depth in the Navigation lesson) with the full nested path to move between deeply nested routes; Next.js resolves the entire path against the app/ folder structure automatically.

import Link from "next/link";

export default function DashboardNav() {
  return (
    <nav>
      <Link href="/dashboard/settings">Settings</Link>
      <Link href="/dashboard/settings/profile">Profile</Link>
    </nav>
  );
}

Common Mistakes

  • Expecting a parent layout to remount (and reset its state) on every navigation within its own subtree.
  • Duplicating navigation UI in every nested layout instead of placing it once in a shared parent layout.
  • Forgetting that a folder without its own layout.tsx simply inherits the nearest parent layout — it isn't "missing" anything.
  • Nesting nine or ten levels deep for content that would be clearer as flatter routes with route groups.

Key Takeaways

  • Every folder level can optionally add its own layout.tsx, and layouts compose from the root down.
  • Deeply nested routes render every applicable layout, wrapped from outermost to innermost.
  • Shared layouts preserve state across navigations between routes that share them.
  • Layouts without a page.tsx at their own level simply organize deeper, nested routes.
  • Use <Link> with the full nested path to navigate directly to any depth.

Pro Tip

If you notice a component's state resetting unexpectedly when you expected it to persist across navigation, check whether the two routes actually share a common layout — moving shared UI one level higher in the folder tree is often the fix.