Skip to main content

JavaScriptでクエリパラメーターを書き換える

実装コード

コピー&ペーストで動くJavaScriptのコードとしては次のようになります。 DevToolsに貼り付けで動作確認が可能です。

const stringify = (targetObject) => {
return Object.entries(targetObject).reduce((queries, current) => {
const key = encodeURIComponent(current[0]);
const value = encodeURIComponent(current[1]);
return (queries += (queries === "" ? "" : "&") + `${key}=${value}`);
}, "")
}

const updateQueryParams = (newKey, newValue) => {
const searchParams = new URLSearchParams(window.location.search);
const nextQueryParams = {};
searchParams.forEach((value, key) => {
nextQueryParams[key] = value;
});
nextQueryParams[newKey] = newValue;
history.replaceState(null, document.title, `?${stringify(nextQueryParams)}`);
}

TypeScriptバージョン

TypeScriptを利用している場合、大抵の場合はwebpackを通していると考えられるので、stringifyは少し楽をします。

import { stringify } from "querystring";

const updateQueryParams = (newKey: string, newValue: string): void => {
const searchParams = new URLSearchParams(window.location.search);
const nextQueryParams: { [key: string]: string } = {};
searchParams.forEach((value, key) => {
nextQueryParams[key] = value;
});
nextQueryParams[newKey] = newValue;
history.replaceState(null, document.title, `?${stringify(nextQueryParams)}`);
}

解説

URLSearchParams

URLSearchParamsを利用してクエリパラメーターを扱いやすくします。 ただしこのAPIはInternet Explorerで未サポートであり、Safariも10以下は未サポートとなっています。 が、そういったブラウザやバージョンは進化の妨げになるので切り捨てましょう。 もし対応が必要ならURLSearchParams Polyfilを充てましょう。

const searchParams = new URLSearchParams(window.location.search);

現在のクエリパラメーターはforEachを使うと内部のgeneratorがvalue, keyを引数としてループを回します。 現在のクエリパラメーターのペアを維持しつつ、新しいクエリパラメーターに置き換えていきます。

history.replaceState

HTML5から実装されたAPIで、現在の履歴(=URL)を操作できます。 似たAPIとしてpushStateがありますが、これを利用すると履歴が増えていく違いがあります。

参考