layout.js
layoutは、routes の間で共有される 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 ディレクトリの最上位の layout です。これは <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プロパティを受け入れ、使用する必要がある layout コンポーネント。レンダリング中にchildrenは route セグメントで埋められ、その layout がラップしています。これらは主に子の Layout (存在する場合)や Pageの component になりますが、適用可能な場合は Loading や Error などの特別なファイルもある場合があります。
params (optional)
そのdynamic route parametersから root セグメントからその layout までの object 。
| Example | 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'] } |
For example:
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>
}
Good to know
Layout は searchParams を受け取りません
Pagesとは異なり、LayoutComponent は searchParams プロップを受け取りません。これは、共有の layout がナビゲーション中に再レンダリングされないためで、ナビゲーション間で stale な searchParams が生じる可能性があるからです。
Client サイドのナビゲーションを使用するとき、Next.js は自動的に、二つの routes の間の共通の layout 以下のページの部分だけをレンダリングします。
例えば、以下のディレクトリ構造において、dashboard/layout.tsx は、/dashboard/settings と /dashboard/analytics の共通の layout となります。
/dashboard/settingsから/dashboard/analyticsへ移動するとき、/dashboard/analyticsの中のpage.tsxは server 上で再レンダリングされますが、dashboard/layout.tsxは再レンダリングされません。なぜなら、それは二つの routes 間で共有される共通の UI だからです。
このパフォーマンス最適化により、 layout を共有するページ間の移動がより迅速になります。なぜならページのデータ取得とレンダリングのみが実行され、共有レイアウトを含む可能性のある全体の route が実行される代わりに、それぞれが独自のデータを fetch する必要がないからです。
dashboard/layout.tsxが再レンダリングされないため、layout Server Component の中のsearchParamsプロップは、ナビゲーション後にstaleになる可能性があります。
- それでは、Page
searchParamsprop またはuseSearchParamshook を使用してください。これは最新のsearchParamsで client 上で再レンダリングされる Client Components です。
Root Layout
appディレクトリには、必ず rootapp/layout.jsを含める必要があります。- root layout は、
<html>と<body>タグを必ず定義しなければなりません。 - あなたは手動で
<head>タグ、例えば<title>や<meta>を root のレイアウトに追加すべきではありません。代わりに、ストリーミングや重複した<head>要素の解消などの高度な要件を自動的に処理するMetadata APIを使用すべきです。 - route groupsを使用して複数の rootLayout を作成することができます。
- 複数の root Layout を跨いでナビゲートすると、フルページのロードが起こります(Client サイドのナビゲーションとは対照的に)。例えば、
app/(shop)/layout.jsを使用する/cartからapp/(marketing)/layout.jsを使用する/blogに移動すると、フルページのロードが起こります。これは、複数の root Layout にのみ適用されます。
- 複数の root Layout を跨いでナビゲートすると、フルページのロードが起こります(Client サイドのナビゲーションとは対照的に)。例えば、
Version History
| Version | Changes |
|---|---|
v13.0.0 | layout 導入されました。 |