レイアウトとページ
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 コンポーネント
動的セグメント
役に立ちましたか?




