ページとレイアウト
Next.js 13のApp Routerでは、ページ、共有レイアウト、テンプレートを簡単に作成するための新しいファイル規約が導入されました。このページでは、Next.jsアプリケーションでこれらの特殊なファイルを使用する方法を説明します。
ページ
ページは、ルートに対して一意のUIです。page.js
ファイルからコンポーネントをエクスポートすることでページを定義できます。ネストされたフォルダを使用してルートを定義し、page.js
ファイルを使用してルートを公開可能にします。
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>
}
// `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コンポーネントをdefault
エクスポートすることでレイアウトを定義できます。コンポーネントは、レンダリング時に子レイアウト(存在する場合)または子ページで埋められるchildren
プロップを受け入れる必要があります。

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>
)
}
知っておくと良いこと:
- 最上位のレイアウトはルートレイアウトと呼ばれます。この必須レイアウトはアプリケーションのすべてのページで共有されます。ルートレイアウトには
html
とbody
タグを含める必要があります。- 任意のルートセグメントは独自のレイアウトを定義できます。これらのレイアウトはそのセグメント内のすべてのページで共有されます。
- ルート内のレイアウトはデフォルトでネストされます。各親レイアウトはReactの
children
プロップを使用して下位の子レイアウトをラップします。- ルートグループを使用して、特定のルートセグメントを共有レイアウトに含めたり除外したりできます。
- レイアウトはデフォルトでサーバーコンポーネントですが、クライアントコンポーネントに設定できます。
- レイアウトはデータを取得できます。詳細はデータ取得セクションを参照してください。
- 親レイアウトとその子の間でデータを渡すことはできません。ただし、ルートで同じデータを複数回取得でき、Reactはパフォーマンスに影響を与えずにリクエストを自動的に重複排除します。
- レイアウトは自身より下位のルートセグメントにアクセスできません。すべてのルートセグメントにアクセスするには、クライアントコンポーネントで
useSelectedLayoutSegment
またはuseSelectedLayoutSegments
を使用できます。- レイアウトには
.js
、.jsx
、または.tsx
ファイル拡張子を使用できます。layout.js
とpage.js
ファイルは同じフォルダに定義できます。レイアウトはページをラップします。
ルートレイアウト(必須)
ルートレイアウトはapp
ディレクトリの最上位で定義され、すべてのルートに適用されます。このレイアウトにより、サーバーから返される初期HTMLを変更できます。
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>
)
}
知っておくと良いこと:
app
ディレクトリには必ずルートレイアウトを含める必要があります。- Next.jsは自動的に
<html>
と<body>
タグを作成しないため、ルートレイアウトでこれらを定義する必要があります。- 組み込みのSEOサポートを使用して
<head>
HTML要素(例:<title>
要素)を管理できます。- ルートグループを使用して複数のルートレイアウトを作成できます。例はこちらを参照してください。
- ルートレイアウトはデフォルトでサーバーコンポーネントであり、クライアントコンポーネントに設定できません。
pages
ディレクトリからの移行: ルートレイアウトは_app.js
と_document.js
ファイルを置き換えます。移行ガイドを参照してください。
レイアウトのネスト
フォルダ内(例:app/dashboard/layout.js
)で定義されたレイアウトは、特定のルートセグメント(例:acme.com/dashboard
)に適用され、それらのセグメントがアクティブなときにレンダリングされます。デフォルトでは、ファイル階層内のレイアウトはネストされており、children
プロップを介して子レイアウトをラップします。

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

ルートグループを使用して、特定のルートセグメントを共有レイアウトに含めたり除外したりできます。
テンプレート
テンプレートは、各子レイアウトまたはページをラップする点でレイアウトと似ています。ルート間で永続化され状態を保持するレイアウトとは異なり、テンプレートはナビゲーション時に子ごとに新しいインスタンスを作成します。つまり、テンプレートを共有するルート間をユーザーが移動すると、コンポーネントの新しいインスタンスがマウントされ、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>
<head>
の変更
app
ディレクトリでは、組み込みのSEOサポートを使用してtitle
やmeta
などの<head>
HTML要素を変更できます。
メタデータは、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>
要素の重複排除などの高度な要件を自動的に処理するMetadata APIを使用してください。