layout.js
layout
ファイルは、Next.js アプリケーションでレイアウトを定義するために使用されます。
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
ルートレイアウトは、ルート app
ディレクトリにある最上位のレイアウトです。<html>
および <body>
タグや、その他のグローバルに共有される UI を定義するために使用されます。
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
リファレンス
Props
children
(必須)
レイアウトコンポーネントは、children
プロパティを受け入れて使用する必要があります。レンダリング中、children
には、レイアウトがラップしているルートセグメントが設定されます。これらは主に子レイアウト(存在する場合)またはページのコンポーネントになりますが、該当する場合はLoadingやErrorなどの他の特別なファイルになる場合もあります。
params
(オプション)
ルートセグメントのルートからそのレイアウトまでの動的ルートパラメーターオブジェクトを含むオブジェクトに解決されるプロミス。
export default async function Layout({
params,
}: {
params: Promise<{ team: string }>
}) {
const team = (await params).team
}
ルートの例 | URL | params |
---|---|---|
app/dashboard/[team]/layout.js | /dashboard/1 | Promise<{ team: '1' }> |
app/shop/[tag]/[item]/layout.js | /shop/1/2 | Promise<{ tag: '1', item: '2' }> |
app/blog/[...slug]/layout.js | /blog/1/2 | Promise<{ slug: ['1', '2'] }> |
params
プロパティはプロミスなので、値にアクセスするにはasync/await
または React のuse
関数を使用する必要があります。- バージョン 14 以前では、
params
は同期的な prop でした。後方互換性を保つため、Next.js 15 では引き続き同期的にアクセスできますが、この動作は将来的に非推奨となる予定です。
- バージョン 14 以前では、
ルートレイアウト
app
ディレクトリには、ルートとなる app/layout.js
を **必ず** 含める必要があります。
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>{children}</body>
</html>
)
}
- ルートレイアウトは、
<html>
と<body>
タグを **必ず** 定義する必要があります。- ルートレイアウトに
<title>
や<meta>
などの<head>
タグを手動で追加するべきでは **ありません**。代わりに、Metadata API を使用する必要があります。これは、ストリーミングや<head>
要素の重複排除などの高度な要件を自動的に処理します。
- ルートレイアウトに
- 複数のルートレイアウトを作成するには、ルートグループを使用できます。
- **複数のルートレイアウト間** をナビゲートすると、(クライアントサイドナビゲーションではなく) **ページ全体のリロード** が発生します。たとえば、
app/(shop)/layout.js
を使用する/cart
から、app/(marketing)/layout.js
を使用する/blog
へナビゲートすると、ページ全体のリロードが発生します。これは、**複数のルートレイアウト** にのみ適用されます。
- **複数のルートレイアウト間** をナビゲートすると、(クライアントサイドナビゲーションではなく) **ページ全体のリロード** が発生します。たとえば、
注意点
レイアウトは 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
は、2 つのルート間で共有される共通の UI であるため、**再レンダリングされません**。
このパフォーマンス最適化により、レイアウトを共有するページ間のナビゲーションが高速になります。これは、共有レイアウトが独自のデータをフェッチする可能性があるルート全体ではなく、ページのデータフェッチとレンダリングのみを実行する必要があるためです。
dashboard/layout.tsx
は再レンダリングされないため、レイアウトサーバーコンポーネントの searchParams
prop は、ナビゲーション後に **古くなる** 可能性があります。
代わりに、ページ searchParams
prop、またはレイアウト内のクライアントコンポーネントの useSearchParams
フックを使用してください。これは、最新の searchParams
でクライアント上で再レンダリングされます。
レイアウトは pathname
にアクセスできません
レイアウトは pathname
にアクセスできません。これは、レイアウトがデフォルトでサーバーコンポーネントであり、クライアントサイドナビゲーション中に再レンダリングされないため、ナビゲーション間で pathname
が古くなる可能性があるためです。古くなることを防ぐために、Next.js はルートのすべてのセグメントを再フェッチする必要があり、キャッシュの利点が失われ、ナビゲーション時の RSC ペイロードサイズが増加します。
代わりに、pathname に依存するロジックをクライアントコンポーネントに抽出し、レイアウトにインポートできます。クライアントコンポーネントはナビゲーション中に再レンダリングされる (ただし、再フェッチはされない) ため、usePathname
などの Next.js フックを使用して現在の pathname にアクセスし、古くなることを防ぐことができます。
import { ClientComponent } from '@/app/ui/ClientComponent'
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<ClientComponent />
{/* Other Layout UI */}
<main>{children}</main>
<>
)
}
一般的な pathname
パターンは、params
prop で実装することもできます。
詳細については、例セクションを参照してください。
例
params
に基づいてコンテンツを表示する
動的ルートセグメントを使用すると、params
prop に基づいて特定のコンテンツを表示またはフェッチできます。
export default async function DashboardLayout({
children,
params,
}: {
children: React.ReactNode
params: Promise<{ team: string }>
}) {
const { team } = await params
return (
<section>
<header>
<h1>Welcome to {team}'s Dashboard</h1>
</header>
<main>{children}</main>
</section>
)
}
クライアントコンポーネントで params
を読み取る
クライアントコンポーネント (async
にすることはできません) で params
を使用するには、React の use
関数を使用して、promise を読み取ることができます。
'use client'
import { use } from 'react'
export function Page({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = use(params)
}
バージョン履歴
バージョン | 変更点 |
---|---|
v15.0.0-RC | params が promise になりました。codemod が利用可能です。 |
v13.0.0 | layout が導入されました。 |
お役に立ちましたか?