layout.js

A layout is UI that is shared between routes.

app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return <section>{children}</section>;
}

Props

children (required)

Layout components should accept and use a children prop. During rendering, children will be populated with the route segments the layout is wrapping. These will primarily be the component of a child Layout (if it exists) or Page, but could also be other special files like Loading or Error when applicable.

params (optional)

The dynamic route parameters object from the root segment down to that layout.

ExampleURLparams
app/dashboard/[team]/layout.js/dashboard/1{ team: '1' }
app/shop/[tag]/[item]/layout.js/shop/1/2{ tag: '1', item: '2' }
app/blog/[...slug]/layout.js/blog/1/2{ slug: ['1', '2'] }

For example:

app/shop/[tag]/[item]/layout.ts
export default function ShopLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: {
    tag: string;
    item: string;
  }
}) {
  // URL -> /shop/shoes/nike-air-max-97
  // `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
  return <section>{children}</section>;
}

Good to know

General

  • Unlike Pages, Layout components do not receive the searchParams prop. This is because a shared layout is not re-rendered during navigation which could lead to stale searchParams between navigations.

    Detailed explanation

    When using client-side navigation, Next.js automatically only renders the part of the page below the common layout between two routes.

    For example, in the following directory structure, dashboard/layout.tsx is the common layout for both /dashboard and /dashboard/settings:

    app
    └── dashboard
        ├── layout.tsx
        ├── page.tsx
        └── settings
            └── page.tsx
    

    When navigating from /dashboard to /dashboard/settings, dashboard/settings/page.tsx will be rendered on the server because it the segment that changed, while dashboard/layout.tsx will not be re-rendered because it is a common layout between the two routes.

    This performance optimization allows navigation between pages that share a layout to be quicker as only the data fetching and rendering for the page has to run, instead of the entire route that could include shared layouts that fetch their own data.

    Because dashboard/layout.tsx doesn't re-render, reading a searchParams prop in the layout Server Component would become stale when navigating.

  • Instead, use the Page searchParams prop or the useSearchParams hook in a Client Component, which is re-rendered on the client with the latest searchParams.

Root Layouts

  • The app directory must include a root app/layout.js.
  • The root layout must define <html> and <body> tags.
  • You can use route groups to create multiple root layouts.
    • Navigating across multiple root layouts will cause a full page load (as opposed to a client-side navigation). For example, navigating from /cart that uses app/(shop)/layout.js to /blog that uses app/(marketing)/layout.js will cause a full page load. This only applies to multiple root layouts.

Next Steps