複雑なアプリケーションでは、予め定義されたパスを用いてルートを定義するだけでは不十分な場合があります。Next.js では [param] のようにしてページ名に角括弧(ブラケット)を使うことで動的なルーティング(別名 slug や pretty url など)を作成できます。
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
Read our docs for Linking between pages to learn more.
動的ルーティングは角括弧(ブラケット)のなかに 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, などにマッチします。
その時 query は以下のようになります:
{ } // GET `/post` (空オブジェクト)
{ "slug": ["a"] } // `GET /post/a` (単一要素の配列)
{ "slug": ["a", "b"] } // `GET /post/a/b` (複数要素の配列)
予め定義されたルートは動的ルーティングよりも優先され、動的ルーティングはすべてのルートを受け取りよりも優先されます。以下の例をみてください:
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 などにはマッチしません。Automatic Static Optimizationによって静的に最適化されたページはルートパラメータが指定されていない状態でハイドレートされます。つまり、query は {} のように空オブジェクトになります。
ハイドレート後に Next.js はアプリケーションの更新をトリガーにして、 query オブジェクトにルートパラメータを提供します。
For more information on what to do next, we recommend the following sections: