Madogiwa Blog

主に技術系の学習メモに使っていきます。

JavaScript: HistoryAPIとURLSearchParamsを使ってURLのSearchQueryをいい感じに追加するメモ

非同期での検索処理を実装したりするとHistoryAPIを使って動的にブラウザのURLを書き換えたりしますが、URLSearchParamsと組み合わせて使うといい感じに検索条件をSearchQueryに追加できそうだったのでメモ📝

developer.mozilla.org

developer.mozilla.org

SearchQueryをいい感じに追加する

以下のような感じで実装すると検索条件のSearchQuery(?foo=bar)追加がappendParamToUrlの引数にkey,valueを渡すだけでできるので便利そうでした。 URLSearchParamsで扱いやすいようにSearchQueryを文字列 - Objectに相互変換して更新し、history.replaceStateで元のURLを更新してあげる感じで実装してみました📝

// URLSearchParamsを使ってSearchQueryの文字列をObjectに変換
// "keyword=foo" -> { keyword: 'foo' }
const urlSearchToObject = (search: string): { [k: string]: string } => {
  const params = new URLSearchParams(search);
  return Object.fromEntries(params);
};

// URLSearchParamsを使ってObjectをSearchQueryの文字列に変換
export const objectToUrlSearch = (object: Record<string, string>): string => {
  const searchParams = new URLSearchParams(object);
  return searchParams.toString();
};

// SearchQueryに`?`を付けるか付けないかが紛らわしいので型レベルでチェックできるようにした
type UrlQuery = `?${string}` | "";

// HistoryAPIを使ったURLの書き換え
const replaceUrl = (path: string, query: UrlQuery) => {
  history.replaceState({}, "", `${path}${query}`);
};

// 渡されたkey,valueをSearchQuery追記してURLに反映する
const appendParamToUrl = (key: string, value: string) => {
  const searchParams = urlSearchToObject(location.search);
  searchParams[key] = value;
  replaceUrl(location.pathname, `?${objectToUrlSearch(searchParams)}`);
};

const searchWord = "search word"
appendParamToUrl("searchWord", searchWord)
// -> example.com?foo=bar

おわりに

HistoryAPIとURLSearchParams便利ですね!!

参考

zenn.dev

stackoverflow.com