layout.js
レイアウト (layout) とは、複数のルート間で共有される UI です。
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
export default function DashboardLayout({ children }) {
return <section>{children}</section>
}
ルートレイアウト (root layout) は、ルート app
ディレクトリの最上位レイアウトです。<html>
タグや <body>
タグ、その他のグローバルに共有される UI を定義するために使用されます。
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
Props
children
(必須)
レイアウトコンポーネントは children
prop を受け取り、使用する必要があります。レンダリング時、children
にはレイアウトがラップしているルートセグメントが含まれます。これには主に子の レイアウト コンポーネント(存在する場合)や ページ コンポーネントが含まれますが、状況に応じて ローディング や エラー などの特別なファイルも含まれる可能性があります。
params
(オプション)
ルートセグメントからそのレイアウトまでの 動的ルートパラメータ オブジェクトです。
例 | URL | params |
---|---|---|
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'] } |
例:
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>
}
export default function ShopLayout({ children, params }) {
// URL -> /shop/shoes/nike-air-max-97
// `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
return <section>{children}</section>
}
知っておくと便利な情報
レイアウトは searchParams
を受け取らない
ページ とは異なり、レイアウトコンポーネントは searchParams
prop を受け取りません。これは、共有レイアウトが ナビゲーション中に再レンダリングされない ためで、ナビゲーション間で searchParams
が古くなる可能性があるからです。
クライアントサイドナビゲーションを使用する場合、Next.js は自動的に2つのルート間で共通のレイアウトの下にあるページ部分のみをレンダリングします。
例えば、以下のディレクトリ構造では、dashboard/layout.tsx
が /dashboard/settings
と /dashboard/analytics
の両方の共通レイアウトになります:

/dashboard/settings
から /dashboard/analytics
にナビゲートする場合、/dashboard/analytics
の page.tsx
はサーバー上で再レンダリングされますが、dashboard/layout.tsx
は再レンダリングされません。これは両ルート間で共有される共通 UI だからです。
このパフォーマンス最適化により、レイアウトを共有するページ間のナビゲーションが高速化されます。ページのデータ取得とレンダリングのみが実行され、独自のデータを取得する可能性のある共有レイアウトを含むルート全体が実行されることはありません。
dashboard/layout.tsx
が再レンダリングされないため、レイアウトのサーバーコンポーネント内の searchParams
prop はナビゲーション後に 古くなる 可能性があります。
- 代わりに、ページの
searchParams
prop を使用するか、クライアントコンポーネント内でuseSearchParams
フックを使用してください。これらは最新のsearchParams
でクライアント側で再レンダリングされます。
ルートレイアウト
app
ディレクトリには必ずルートapp/layout.js
を含める必要があります。- ルートレイアウトには必ず
<html>
タグと<body>
タグを定義する必要があります。- ルートレイアウトに
<title>
や<meta>
などの<head>
タグを手動で追加するべきではありません。代わりに、ストリーミングや<head>
要素の重複排除などの高度な要件を自動的に処理する メタデータ API を使用してください。
- ルートレイアウトに
- ルートグループ を使用して複数のルートレイアウトを作成できます。
- 複数のルートレイアウト間をナビゲート すると、ページ全体の再読み込み が発生します(クライアントサイドナビゲーションとは異なります)。例えば、
app/(shop)/layout.js
を使用する/cart
からapp/(marketing)/layout.js
を使用する/blog
にナビゲートすると、ページ全体が再読み込みされます。これは 複数のルートレイアウト にのみ適用されます。
- 複数のルートレイアウト間をナビゲート すると、ページ全体の再読み込み が発生します(クライアントサイドナビゲーションとは異なります)。例えば、
バージョン履歴
バージョン | 変更点 |
---|---|
v13.0.0 | layout が導入されました。 |