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
searchParams
prop またはuseSearchParams
hook を使用してください。これは最新の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 導入されました。 |