レイアウトとページ
Next.js ではファイルシステムベースのルーティングが採用されており、フォルダやファイルを使用してルートを定義できます。このページでは、レイアウトとページを作成し、それらの間でリンクする方法について説明します。
ページの作成
ページとは、特定のルートでレンダリングされる UI です。ページを作成するには、app ディレクトリ内に page ファイルを追加し、React コンポーネントをデフォルトエクスポートします。たとえば、インデックスページ(/)を作成するには、次のようになります。

export default function Page() {
return <h1>Hello Next.js!</h1>
}レイアウトの作成
レイアウトとは、複数のページで共有される UI です。ナビゲーション時、レイアウトは状態を保持し、インタラクティブなままで、再レンダリングされません。
レイアウトは、layout ファイルから React コンポーネントをデフォルトエクスポートすることで定義できます。コンポーネントは children プロップを受け取る必要があり、これはページまたは別の レイアウト にすることができます。
たとえば、インデックスページを子として受け入れるレイアウトを作成するには、app ディレクトリ内に layout ファイルを追加します。

export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* Layout UI */}
{/* Place children where you want to render a page or nested layout */}
<main>{children}</main>
</body>
</html>
)
}上記のレイアウトは、app ディレクトリのルートに定義されているため、ルートレイアウトと呼ばれます。ルートレイアウトは必須であり、html および body タグを含める必要があります。
ネストされたルートの作成
ネストされたルートとは、複数の URL セグメントで構成されるルートのことです。たとえば、/blog/[slug] ルートは 3 つのセグメントで構成されています。
/(ルートセグメント)blog(セグメント)[slug](リーフセグメント)
Next.js では、
- フォルダは、URL セグメントにマッピングされるルートセグメントを定義するために使用されます。
- ファイル(
pageやlayoutなど)は、セグメントに対して表示される UI を作成するために使用されます。
ネストされたルートを作成するには、フォルダを互いにネストできます。たとえば、/blog のルートを追加するには、app ディレクトリ内に blog という名前のフォルダを作成します。次に、/blog を公開可能にするには、page.tsx ファイルを追加します。

// Dummy imports
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'
export default async function Page() {
const posts = await getPosts()
return (
<ul>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</ul>
)
}フォルダのネストを続けることで、ネストされたルートを作成できます。たとえば、特定のブログ投稿のルートを作成するには、blog 内に新しい [slug] フォルダを作成し、page ファイルを追加します。

function generateStaticParams() {}
export default function Page() {
return <h1>Hello, Blog Post Page!</h1>
}フォルダ名を角括弧(例: [slug])で囲むと、動的ルートセグメントが作成され、データから複数のページを生成するために使用されます。例: ブログ投稿、製品ページなど。
レイアウトのネスト
デフォルトでは、フォルダ階層内のレイアウトもネストされるため、children プロップを介して子レイアウトをラップします。特定のルートセグメント(フォルダ)に layout を追加することで、レイアウトをネストできます。
たとえば、/blog ルートのレイアウトを作成するには、blog フォルダ内に新しい layout ファイルを追加します。

export default function BlogLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}上記の 2 つのレイアウトを組み合わせると、ルートレイアウト(app/layout.js)がブログレイアウト(app/blog/layout.js)をラップし、それがブログ(app/blog/page.js)とブログ投稿ページ(app/blog/[slug]/page.js)をラップします。
動的セグメントの作成
動的セグメントを使用すると、データから生成されるルートを作成できます。たとえば、個々のブログ投稿ごとにルートを手動で作成する代わりに、動的セグメントを作成してブログ投稿データに基づいてルートを生成できます。
動的セグメントを作成するには、セグメント(フォルダ)名を角括弧で囲みます: [segmentName]。たとえば、app/blog/[slug]/page.tsx ルートでは、[slug] が動的セグメントです。
export default async function BlogPostPage({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
const post = await getPost(slug)
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
)
}動的セグメントと params プロップスについて詳しくは、動的セグメントを参照してください。
動的セグメント内の ネストされたレイアウトでも、params プロップスにアクセスできます。
検索パラメータを使用したレンダリング
サーバーコンポーネントのページでは、searchParams プロップを使用して検索パラメータにアクセスできます。
export default async function Page({
searchParams,
}: {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const filters = (await searchParams).filters
}searchParams を使用すると、ページは動的レンダリングの対象となります。これは、検索パラメータを読み取るために着信リクエストが必要になるためです。
クライアントコンポーネントは、useSearchParams フックを使用して検索パラメータを読み取ることができます。
useSearchParams については、静的レンダリングおよび動的レンダリングルートで詳しく説明しています。
何を使用し、いつ使用するか
- 検索パラメータを使用してページデータを読み込む必要がある場合(例: ページネーション、データベースからのフィルタリング)は、
searchParamsプロップを使用します。 - 検索パラメータがクライアントでのみ使用される場合(例: プロップスで既に読み込まれたリストのフィルタリング)は、
useSearchParamsを使用します。 - 簡単な最適化として、コールバックまたはイベントハンドラーで
new URLSearchParams(window.location.search)を使用して、再レンダリングをトリガーせずに検索パラメータを読み取ることができます。
ページ間のリンク
ルート間のナビゲーションには、<Link> コンポーネントを使用できます。<Link> は、HTML の <a> タグを拡張した組み込みの Next.js コンポーネントで、プリフェッチとクライアントサイドナビゲーションを提供します。
たとえば、ブログ投稿のリストを生成するには、next/link から <Link> をインポートし、コンポーネントに href プロップを渡します。
import Link from 'next/link'
export default async function Post({ post }) {
const posts = await getPosts()
return (
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}知っておくと良いこと:
<Link>は、Next.js でルート間をナビゲーションする主な方法です。より高度なナビゲーションには、useRouterフックを使用することもできます。
ルートプロップスヘルパー
Next.js は、ルート構造から params と名前付きスロットを推論するユーティリティ型を公開しています。
- PageProps:
pageコンポーネントのプロップス。paramsとsearchParamsを含みます。 - LayoutProps:
layoutコンポーネントのプロップス。childrenおよび名前付きスロット(例:@analyticsのようなフォルダ)を含みます。
これらはグローバルに利用可能なヘルパーであり、next dev、next build、または next typegen のいずれかを実行すると生成されます。
export default async function Page(props: PageProps<'/blog/[slug]'>) {
const { slug } = await props.params
return <h1>Blog post: {slug}</h1>
}export default function Layout(props: LayoutProps<'/dashboard'>) {
return (
<section>
{props.children}
{/* If you have app/dashboard/@analytics, it appears as a typed slot: */}
{/* {props.analytics} */}
</section>
)
}知っておくと良いこと
- 静的ルートでは、
paramsは{}に解決されます。PageProps、LayoutPropsはグローバルヘルパーです。インポートは不要です。- 型は
next dev、next build、またはnext typegenの実行中に生成されます。
APIリファレンス
リンクとナビゲーション
layout.js
page.js
Link コンポーネント
動的セグメント
役に立ちましたか?




