【Next.js】クエリパラメータを渡しつつ遷移先のURLには表示させない方法
Next.jsにおいて、クエリパラメータを渡しつつ遷移先のURLには表示させずに参照する方法です。
あまりこういったケースはないかもしれませんが、以前ハマってしまったので方法をふたつ書いておきます。
⛰ 目的
- ページ遷移時にクエリパラメータをオブジェクトの形で渡したい
- 遷移先のURLにはクエリパラメータを表示させたくない
- 遷移先で渡されたクエリパラメータを参照したい
- 遷移先へ直リンクした際はクエリパラメータは存在しないようにしたい
📦 前提
- 特定の箇所で一時的に参照するため、Redux(などの状態管理ライブラリ)は使わない
-
/pages配下のファイル同士の受け渡しのため、Propsは使えない
💡 結論
- Nextの
<Link>コンポーネントで実現できる -
router.push()で実現できる
Linkコンポーネントで実装する場合
/**
* 遷移前のページ
*/
import Link from "next/link";
// 受け渡すクエリパラメータ
const query = {
id: 1,
name: "yakkun",
};
export default function First() {
return (
<Link href={{ pathname: "second", query: query }} as="second">
<a>Secondへ遷移する</a>
</Link>
);
}
/**
* 遷移後のページ
*/
import { useRouter } from "next/router";
export default function Second() {
const router = useRouter();
return (
<ul>
<li>id:{" " + router.query.id}</li>
<li>name:{" " + router.query.name}</li>
</ul>
);
}
ブラウザでの挙動

- リンクをクリックして
/secondへ遷移 - URLにクエリパラメータが表示されていない
- 値は参照できている
-
直リンクの際は
undefinedになっている(遷移時にクエリパラメータが渡されるため)
上記が確認できました。
router.push()で実装する場合
/**
* 遷移前のページ
*/
import { useRouter } from "next/router";
// 受け渡すクエリパラメータ
const query = {
id: 1,
name: "yakkun",
};
export default function First() {
const router = useRouter();
const nextPage = () => {
router.push({ pathname: "second", query: query }, "second");
};
return <button onClick={() => nextPage()}>secondへ遷移する</button>;
}
/**
* 遷移後のページ
*/
import { useRouter } from "next/router";
export default function Second() {
const router = useRouter();
return (
<ul>
<li>id:{" " + router.query.id}</li>
<li>name:{" " + router.query.name}</li>
</ul>
);
}
ブラウザでの挙動

まぁ、さっきと同じです。
📖 解説
Linkの解説
Nextが提供している<Link>コンポーネントは、通常href={"/hoge/huga"}のようにパスを指定します。
ただこのhrefはオブジェクトも受け付けており、pathname, queryというキーが使用できます。
それぞれ名称の通りパスとクエリパラメータを渡すことができます。
そして、今回重要なのはasというオプションです。
asには遷移先で表示するURLを渡すことができます。
// 省略
<Link href={{ pathname: "second", query: query }} as="second">
<a>Secondへ遷移する</a>
</Link>
);
}
つまり、どんなクエリパラメータを渡そうともasにより指定されたパスパラメータが遷移先のURLに表示されるという仕組みです。
上記の例では遷移先のURLは/secondとなります。
router.push()の解説
Nextの<Link>コンポーネントと同様に、SPAの挙動を取るrouter.push()でも同様の実装ができます。
// 省略
const router = useRouter();
const nextPage = () => {
router.push({ pathname: "second", query: query }, "second");
};
return <button onClick={() => nextPage()}>secondへ遷移する</button>;
}
関数nextPageを定義し、<button>タグのonClickイベントに渡しました。
nextPageではrouter.push()にふたつの引数を渡しています。
第一引数にはurlを受け付けるのですが、<Link>同様オブジェクトでpathnameとqueryを渡すことができます。
そして、第二引数には<Link>コンポーネントにおけるasに相当する文字列を渡すことができ、遷移先のURLにどう表示されるかを指定することができます。
🖋 まとめ
ふたつとも同じ挙動を取るためどちらでも実現できます。
ただ<Link>コンポーネントにはクリックイベントを指定できないため、遷移と同時に値を取得する処理などを挟む場合はrouter.push()を使うとよいと思います。
また、非表示であれクエリパラメータはrouterに格納されているため、遷移先で参照するにはuseRouter()が必要になり、router.query.{hoge}の形を取ることになります。
🦄 おわり
今回はクエリパラメータを渡しつつ遷移先のURLに表示させない方法をご紹介しました。
本来であればクエリパラメータやasは動的ルーティングで活躍すると思うのですが、こういった使い方もできるよ〜というお話でした。
それではまた。
Discussion