ページとレイアウト
特別なファイル layout.js、page.js、および template.js を使用すると、ルートのUIを作成できます。このページでは、これらの特別なファイルをいつどのように使用するかを説明します。
ページ
ページはルートに固有のUIです。page.js
ファイルからコンポーネントをデフォルトエクスポートすることでページを定義できます。
例えば、index
ページを作成するには、app
ディレクトリ内に page.js
ファイルを追加します:

// `app/page.tsx` は `/` URL のUIです
export default function Page() {
return <h1>こんにちは、ホームページ!</h1>
}
// `app/page.js` は `/` URL のUIです
export default function Page() {
return <h1>こんにちは、ホームページ!</h1>
}
さらにページを作成するには、新しいフォルダを作成し、その中に page.js
ファイルを追加します。例えば、/dashboard
ルートのページを作成するには、dashboard
という新しいフォルダを作成し、その中に page.js
ファイルを追加します:
// `app/dashboard/page.tsx` は `/dashboard` URL のUIです
export default function Page() {
return <h1>こんにちは、ダッシュボードページ!</h1>
}
// `app/dashboard/page.js` は `/dashboard` URL のUIです
export default function Page() {
return <h1>こんにちは、ダッシュボードページ!</h1>
}
知っておくと良いこと:
- ページには
.js
、.jsx
、または.tsx
ファイル拡張子を使用できます。- ページは常にルートサブツリーのリーフです。
- ルートセグメントを公開するには
page.js
ファイルが必要です。- ページはデフォルトでサーバーコンポーネントですが、クライアントコンポーネントに設定できます。
- ページはデータを取得できます。詳細はデータフェッチングセクションを参照してください。
レイアウト
レイアウトは複数のルート間で共有されるUIです。ナビゲーション時に、レイアウトは状態を保持し、インタラクティブなまま再レンダリングされません。レイアウトはネストすることもできます。
layout.js
ファイルからReactコンポーネントをデフォルトエクスポートすることでレイアウトを定義できます。コンポーネントはレンダリング時に子レイアウト(存在する場合)またはページが埋められる children
プロップを受け入れる必要があります。
例えば、このレイアウトは /dashboard
と /dashboard/settings
ページで共有されます:

export default function DashboardLayout({
children, // ページまたはネストされたレイアウトになります
}: {
children: React.ReactNode
}) {
return (
<section>
{/* ヘッダーやサイドバーなどの共有UIを含める */}
<nav></nav>
{children}
</section>
)
}
export default function DashboardLayout({
children, // ページまたはネストされたレイアウトになります
}) {
return (
<section>
{/* ヘッダーやサイドバーなどの共有UIを含める */}
<nav></nav>
{children}
</section>
)
}
ルートレイアウト(必須)
ルートレイアウトは app
ディレクトリの最上位で定義され、すべてのルートに適用されます。このレイアウトは必須で、サーバーから返される初期HTMLを変更できるように html
タグと body
タグを含める必要があります。
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* レイアウトUI */}
<main>{children}</main>
</body>
</html>
)
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{/* レイアウトUI */}
<main>{children}</main>
</body>
</html>
)
}
レイアウトのネスト
デフォルトでは、フォルダ階層内のレイアウトはネストされており、children
プロップを介して子レイアウトをラップします。特定のルートセグメント(フォルダ)内に layout.js
を追加することでレイアウトをネストできます。
例えば、/dashboard
ルートのレイアウトを作成するには、dashboard
フォルダ内に新しい layout.js
ファイルを追加します:

export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
export default function DashboardLayout({ children }) {
return <section>{children}</section>
}
上記の2つのレイアウトを組み合わせると、ルートレイアウト(app/layout.js
)がダッシュボードレイアウト(app/dashboard/layout.js
)をラップし、それが app/dashboard/*
内のルートセグメントをラップします。
2つのレイアウトは次のようにネストされます:

知っておくと良いこと:
- レイアウトには
.js
、.jsx
、または.tsx
ファイル拡張子を使用できます。- ルートレイアウトのみが
<html>
タグと<body>
タグを含めることができます。- 同じフォルダに
layout.js
とpage.js
ファイルが定義されている場合、レイアウトはページをラップします。- レイアウトはデフォルトでサーバーコンポーネントですが、クライアントコンポーネントに設定できます。
- レイアウトはデータを取得できます。詳細はデータフェッチングセクションを参照してください。
- 親レイアウトとその子の間でデータを渡すことはできません。ただし、ルートで同じデータを複数回フェッチでき、Reactはパフォーマンスに影響を与えずにリクエストを自動的に重複排除します。
- レイアウトは自身より下のルートセグメントにアクセスできません。すべてのルートセグメントにアクセスするには、クライアントコンポーネントで
useSelectedLayoutSegment
またはuseSelectedLayoutSegments
を使用できます。- ルートグループを使用して、特定のルートセグメントを共有レイアウトに含めたり除外したりできます。
- ルートグループを使用して複数のルートレイアウトを作成できます。例はこちらを参照してください。
pages
ディレクトリからの移行: ルートレイアウトは_app.js
と_document.js
ファイルを置き換えます。移行ガイドを参照してください。
テンプレート
テンプレートは各子レイアウトまたはページをラップする点でレイアウトと似ています。ルート間で持続し状態を保持するレイアウトとは異なり、テンプレートはナビゲーション時に子ごとに新しいインスタンスを作成します。つまり、テンプレートを共有するルート間をユーザーが移動すると、コンポーネントの新しいインスタンスがマウントされ、DOM要素が再作成され、状態は保持されず、エフェクトが再同期されます。
これらの特定の動作が必要な場合、テンプレートはレイアウトよりも適切な選択肢となります。例えば:
useEffect
(ページビューのロギングなど)やuseState
(ページごとのフィードバックフォームなど)に依存する機能- デフォルトのフレームワーク動作を変更する場合。例えば、レイアウト内のサスペンス境界は、レイアウトが最初にロードされたときのみフォールバックを表示し、ページ切り替え時には表示しません。テンプレートでは、ナビゲーションごとにフォールバックが表示されます。
テンプレートは template.js
ファイルからデフォルトのReactコンポーネントをエクスポートすることで定義できます。コンポーネントは children
プロップを受け入れる必要があります。

export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}
export default function Template({ children }) {
return <div>{children}</div>
}
ネストに関して、template.js
はレイアウトとその子の間にレンダリングされます。簡略化した出力は次のようになります:
<Layout>
{/* テンプレートには一意のキーが与えられます */}
<Template key={routeParam}>{children}</Template>
</Layout>
メタデータ
app
ディレクトリでは、メタデータAPIを使用して <head>
HTML要素(title
や meta
など)を変更できます。
メタデータは layout.js
または page.js
ファイルで metadata
オブジェクトまたは generateMetadata
関数をエクスポートすることで定義できます。
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
export const metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
知っておくと良いこと:
<title>
や<meta>
などの<head>
タグをルートレイアウトに手動で追加するべきではありません。代わりに、ストリーミングや<head>
要素の重複排除などの高度な要件を自動的に処理するメタデータAPIを使用してください。
利用可能なメタデータオプションの詳細はAPIリファレンスで確認できます