【Next.js和訳】Routing/Dynamic Routes
この記事について
この記事は、Routing/Dynamic Routesの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
Dynamic Routes
例
複雑なアプリケーションでは、あらかじめ定義されたパスを使ってルートを定義するだけでは不十分な場合があります。Next.js では、ページに括弧([param]
)を追加することで、動的なルート(url slugs や pretty urls など)を作成することができます。
次のようなページ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
などにもマッチします。
マッチしたパラメータは、クエリパラメータ(例では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
オブジェクトにルートパラメーターを付与します。
関連項目
次に何をすべきかについては、以下のセクションをお勧めします。
Discussion