layout.js
layout
ファイルは、Next.jsアプリケーションでレイアウトを定義するために使用されます。
- TypeScript
- JavaScript
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
export default function DashboardLayout({ children }) {
return <section>{children}</section>
}
root レイアウトは、root app
ディレクトリ内の最上位のレイアウトです。これは、<html>
および <body>
タグや他のグローバルに共有されるUIを定義するために使用されます。
- TypeScript
- JavaScript
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
はレイアウトがラップしているルートセグメントで埋められます。これらは主に子Layout(存在する場合)またはPageのコンポーネントですが、適用可能な場合にはLoadingやErrorのような他の特別なファイルであることもあります。
params
(オプション)
root セグメントからそのレイアウトまでの動的ルートパラメータオブジェクトを含むオブジェクトに解決されるプロミスです。
- TypeScript
- JavaScript
export default async function Layout({
params,
}: {
params: Promise<{ team: string }>
}) {
const { team } = await params
}
export default async function Layout({ params }) {
const { team } = await params
}
ルート例 | 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
prop はプロミスであるため、値にアクセスするにはasync/await
または React のuse
関数を使用する必要があります。- バージョン14以前では、
params
は同期的な prop でした。後方互換性を助けるために、Next.js 15 ではまだ同期的にアクセスできますが、この動作は将来的に廃止される予定です。
- バージョン14以前では、
Root レイアウト
app
ディレクトリには root app/layout.js
が必ず含まれていなければなりません。
- TypeScript
- JavaScript
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>{children}</body>
</html>
)
}
export default function RootLayout({ children }) {
return (
<html>
<body>{children}</body>
</html>
)
}
- root レイアウトは
<html>
および<body>
タグを必ず定義しなければなりません。- root レイアウトに
<title>
や<meta>
のような<head>
タグを手動で追加するべきではありません。代わりに、Metadata API を使用するべきです。これは、ストリーミングや<head>
要素の重複排除などの高度な要件を自動的に処理します。
- root レイアウトに
- route groups を使用して、複数の root レイアウトを作成できます。
- 複数の root レイアウトをまたいでナビゲートすると、フルページロードが発生します(クライアントサイドのナビゲーションとは対照的に)。たとえば、
app/(shop)/layout.js
を使用する/cart
からapp/(marketing)/layout.js
を使用する/blog
にナビゲートすると、フルページロードが発生します。これは複数の root レイアウトにのみ適用されます。
- 複数の root レイアウトをまたいでナビゲートすると、フルページロードが発生します(クライアントサイドのナビゲーションとは対照的に)。たとえば、
注意点
レイアウトでリクエストオブジェクトにアクセスするにはどうすればよいですか?
レイアウトで生のリクエストオブジェクトにアクセスすることは意図的にできません。ただし、サーバー専用の関数を通じてheaders
やcookies
にアクセスできます。
Layouts は再レンダリングされません。これらはキャッシュされ、ページ間のナビゲーション時に不要な計算を避けるために再利用されます。レイアウトが生のリクエストにアクセスすることを制限することで、Next.js はレイアウト内での潜在的に遅いまたは高価なユーザーコードの実行を防ぎ、パフォーマンスへの悪影響を避けることができます。
この設計は、異なるページ間でのレイアウトの一貫した予測可能な動作を強制し、開発とデバッグを簡素化します。
レイアウトは searchParams
を受け取りません
Pagesとは異なり、レイアウトコンポーネントは 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
に依存するロジックをクライアントコンポーネントに抽出し、レイアウトにインポートすることができます。クライアントコンポーネントはナビゲーション中に再レンダリングされますが、再フェッチされないため、Next.js のフック(例:usePathname
)を使用して現在の pathname
にアクセスし、古くなるのを防ぐことができます。
- TypeScript
- JavaScript
import { ClientComponent } from '@/app/ui/ClientComponent'
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<ClientComponent />
{/* 他のレイアウトUI */}
<main>{children}</main>
</>
)
}
import { ClientComponent } from '@/app/ui/ClientComponent'
export default function Layout({ children }) {
return (
<>
<ClientComponent />
{/* 他のレイアウトUI */}
<main>{children}</main>
</>
)
}
一般的な pathname
パターンは、params
prop で実装することもできます。
詳細については、例セクションを参照してください。
例
params
に基づいてコンテンツを表示する
動的ルートセグメントを使用して、params
prop に基づいて特定のコンテンツを表示またはフェッチできます。
- TypeScript
- JavaScript
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} のダッシュボード</h1>
</header>
<main>{children}</main>
</section>
)
}
export default async function DashboardLayout({ children, params }) {
const { team } = await params
return (
<section>
<header>
<h1>Welcome to {team} のダッシュボード</h1>
</header>
<main>{children}</main>
</section>
)
}
クライアントコンポーネントで params
を読み取る
クライアントコンポーネント(async
にできない)で params
を使用するには、React の use
関数を使用してプロミスを読み取ります:
- TypeScript
- JavaScript
'use client'
import { use } from 'react'
export default function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = use(params)
}
'use client'
import { use } from 'react'
export default function Page({ params }) {
const { slug } = use(params)
}
バージョン履歴
バージョン | 変更点 |
---|---|
v15.0.0-RC | params がプロミスになりました。codemod が利用可能です。 |
v13.0.0 | layout が導入されました。 |