メインコンテンツまでスキップ

layout.js

レイアウトとは、ルート間で共有される UI です。

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

ルート・レイアウトは、appディレクトリの最上位にあるレイアウトです。<html>タグや<body>タグ、その他グローバルに共有される UI を定義するために使われます。

app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}

Props

children(必須)

レイアウトコンポーネントはchildren prop を受け入れ、使用する必要があります。レンダリング中、childrenにはレイアウトがラップしているルート Segment が入力されます。これらは主に子レイアウト(存在する場合)またはページのコンポーネントになりますが、該当する場合はLoadingErrorのような他の特殊ファイルにもなります。

params(任意)

ルート Segment からそのレイアウトまでの動的なルートパラメーターオブジェクト。

URLparams
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'] }

例:

app/shop/[item]/layout.tsx
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

レイアウトはsearchParamsを受け取らない

ページとは異なり、レイアウト・コンポーネントは searchParams プロップを受け取りません。これは、共有レイアウトがナビゲーションの間に再レンダリングされないため、ナビゲーションの間にsearchParamsは古くなる可能性があるためです。

クライアントサイドでナビゲーションを使用する場合、Next.js は自動的に、2 つのルート間の共通レイアウト以下のページ部分のみをレンダリングします。

たとえば、次のディレクトリ構造では、dashboard/layout.tsx/dashboard/settings/dashboard/analyticsの両方に共通するレイアウトです:

app
└── dashboard
├── layout.tsx
├── settings
│ └── page.tsx
└── analytics
└── page.js

dashboard/settingsから/dashboard/analyticsに遷移する場合、/dashboard/analyticspage.tsxは UI が変更されたためサーバー上でレンダリングされますが、 dashboard/layout.tsxは 2 つのルート間で共通の UI であるため再レンダリングされません。

このパフォーマンスの最適化により、独自のデータをフェッチする共有レイアウトを含むルート全体ではなく、ページのデータフェッチとレンダリングのみが実行されるため、レイアウトを共有するページ間のナビゲーションがより速くなります。

dashboard/layout.tsxは再レンダリングしないため、レイアウト Server Component のsearchParams prop はナビゲーション後に古くなる可能性があります。

  • 代わりに、最新の searchParams によりクライアント上の再レンダリングされる Client Component 内で、ページの searchParams prop、または Client Component の useSearchParams フックを使用します

ルート・レイアウト

  • app ディレクトリにはルートのapp/layout.jsが含まれていなければなりません

  • ルート・レイアウトには<html>タグと<body>タグを定義しなければなりません

    • ルート・レイアウトに<title><meta>のような<head>タグを手動で追加すべきではありません。その代わりに、<head>要素のストリーミングや重複除去といった高度な要件を自動的に処理するMetadata APIを使うべきです
  • ルートグループを使用して、複数のルート・レイアウトを作成できます

    • 複数のルート・レイアウトにまたがってナビゲートすると、(クライアントサイド・ナビゲーションとは対照的に)フルページ・ロードが発生します。例えば、app/(shop)/layout.jsを使用している/cartから、app/(marketing)/layout.jsを使用している/blogに移動すると、全ページがロードされます。これは複数のルート・レイアウトにのみ適用されます。

バージョン履歴

VersionChanges
v13.0.0layoutの導入