複雑なアプリケーションでは、予め定義されたパスを用いてルートを定義するだけでは不十分な場合があります。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: