🚀

【Next.js和訳】Routing/Dynamic Routes

4 min read

この記事について

株式会社 UnReact はプロジェクトの一環としてNext.js ドキュメントの和訳を行っています。

この記事は、Routing/Dynamic Routesの記事を和訳したものです。

記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。

Dynamic Routes

複雑なアプリケーションでは、あらかじめ定義されたパスを使ってルートを定義するだけでは不十分な場合があります。Next.jsでは、ページに括弧([param])を追加することで、動的なルート(url slugsやpretty urlsなど)を作成することができます。

次のようなページpages/post/[pid].jsを考えてみましょう。

pages/post/[pid].js
import { useRouter } from 'next/router'

const Post = () => {
  const router = useRouter()
  const { pid } = router.query

  return <p>Post: {pid}</p>
}

export default Post

/post/1/post/abcなどのルートは、pages/post/[pid].jsでマッチします。マッチしたパスパラメータは、クエリパラメータとしてページに送信され、他のクエリパラメータと結合されます。

たとえば、ルート /post/abc には、次のようなqueryオブジェクトが設定されます。

{ "pid": "abc" }

同様に、ルート /post/abc?foo=bar には次のようなqueryオブジェクトがあります。

{ "foo": "bar", "pid": "abc" }

ただし、ルートのパラメータは、同じ名前のクエリパラメータを上書きします。たとえば、ルート /post/abc?pid=123 は、次のようなqueryオブジェクトになります。

{ "pid": "abc" }

複数のダイナミックルートセグメントも同じように動作します。pages/post/[pid]/[comment].jsというページは、/post/abc/a-commentというルートにマッチし、そのqueryオブジェクトは次のようになります。

{ "pid": "abc", "comment": "a-comment" }

クライアントサイドでのダイナミックルートへの移動は、next/linkで処理されます。上で使用したルートへのリンクを持ちたい場合は、次のようになります。

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/post/abc">
          <a>Go to pages/post/[pid].js</a>
        </Link>
      </li>
      <li>
        <Link href="/post/abc?foo=bar">
          <a>Also goes to pages/post/[pid].js</a>
        </Link>
      </li>
      <li>
        <Link href="/post/abc/a-comment">
          <a>Go to pages/post/[pid]/[comment].js</a>
        </Link>
      </li>
    </ul>
  )
}

export default Home

詳しくは「ページ間のリンク」のドキュメントをご覧ください。

すべてのルートをキャッチ

ダイナミックルートは、大括弧の中に3つのドット(...)を追加することで、すべてのパスを捕捉できるように拡張できます。例えば、以下のようになります。

  • pages/post/[...slug].jsは、/post/aだけでなく、/post/a/b/post/a/b/cなどにもマッチします。

注意
[...param]のようにslug以外の名前も使用できます。

マッチしたパラメータは、クエリパラメータ(例ではslug)としてページに送信され、常に配列となります。したがって、パス /post/a には次のようなqueryオブジェクトが含まれます。

{ "slug": ["a"] }

また、/post/a/bやその他のマッチするパスの場合は、以下のように新しいパラメータが配列に追加されます。

{ "slug": ["a", "b"] }

任意のキャッチオールルート

キャッチオールルートは、パラメータを二重括弧([[...slug]])で囲むことで、オプションにすることができます。

たとえば、pages/post/[[...slug]].jsは、/post/post/a/post/a/b、などにマッチします。

キャッチオールルートとオプショナルキャッチオールルートの主な違いは、オプショナルの場合、パラメータのないルートにもマッチすることです(上記の例では、/post)。

queryオブジェクトは以下の通りです。

{ } // GET `/post` (empty object)
{ "slug": ["a"] } // `GET /post/a` (single-element array)
{ "slug": ["a", "b"] } // `GET /post/a/b` (multi-element array)

注意点

  • 定義済みのルートは動的なルートよりも優先され、動的なルートはすべてのルートをキャッチするよりも優先されます。次の例を見てください。

    • pages/post/create.js - /post/createにマッチします。
    • pages/post/[pid].js - /post/1、/post/abcなどにマッチします。ただし、/post/createにはマッチしません。
    • pages/post/[...slug].js - /post/1/2/post/a/b/cなどにマッチします。ただし、/post/create/post/abcは含まれません。
  • 自動静的最適化によって静的に最適化されたページは、ルートパラメータが提供されずに水和されます。つまり、queryは空のオブジェクト({})になります。

ハイドレーションが完了すると、Next.jsがアプリケーションの更新をトリガーして、queryオブジェクトにルートパラメーターを付与します。

関連項目

次に何をすべきかについては、以下のセクションをお勧めします。

https://nextjs.org/docs/api-reference/next/link
https://nextjs.org/docs/routing/introduction

Discussion

ログインするとコメントできます