「ハッシュ削除」で本当にやりたいこと
ここでの「ハッシュ削除」は、URL の # 以降(フラグメント)をきれいに取り除いた新しい URL を作るユーティリティのことです。
例えば、こんなことをしたい場面があります。
- 一時的に
#modal=loginなどを使ったあと、URL から消したい - ページ内リンク(
#section-3)で移動したあと、ハッシュをリセットしたい - 「状態付きの URL」をユーザーに見せたくないので、ハッシュだけ消したい
ポイントは、「パスやクエリはそのまま残して、# 以降だけをきれいに落とす」ことです。
まずは「ハッシュ」の位置を正しく切り離す
URL の構造をざっくりおさらい
典型的な URL は、こんな構造をしています。
https://example.com/path?query=1#hash-part
このうち、ハッシュ削除で触るのは #hash-part の部分だけです。
https://example.com/path… ベース URL?query=1… クエリ(サーバーに送られる条件)#hash-part… ハッシュ(ブラウザ側だけの状態)
ハッシュ削除ユーティリティは、
「# より前はそのまま」「# 以降は全部捨てる」という動きをします。
文字列としての URL からハッシュを削除する関数
基本の removeHash 実装
まずは、「URL 文字列を受け取って、ハッシュを取り除いた文字列を返す」関数を作ります。
function removeHash(url) {
if (!url) return "";
const str = String(url);
const hashIndex = str.indexOf("#");
if (hashIndex < 0) {
return str;
}
return str.slice(0, hashIndex);
}
JavaScript重要ポイントをかみ砕いて説明する
ここはシンプルですが、ちゃんと理解しておくと応用が効きます。
1. まずは文字列として扱う
const str = String(url);
JavaScripturl に new URL(...) や他の型が来ても、とりあえず文字列化して扱えるようにしています。
2. # の位置を探す
const hashIndex = str.indexOf("#");
JavaScriptindexOf は、見つかれば 0 以上の位置、見つからなければ -1 を返します。
3. ハッシュがなければそのまま返す
if (hashIndex < 0) {
return str;
}
JavaScript# がない URL に対して「ハッシュ削除」をしても、何も変わらないので、そのまま返します。
4. # より前だけを切り出す
return str.slice(0, hashIndex);
JavaScriptslice(0, hashIndex) で、# の手前までを取り出します。# 自体も含まれないので、ハッシュ部分はきれいに消えます。
実際の動きを例で確認する
ハッシュ付き URL の場合
removeHash("https://example.com/docs?page=2#section-3");
// "https://example.com/docs?page=2"
removeHash("/path#top");
// "/path"
removeHash("/path?page=1#tab=profile");
// "/path?page=1"
JavaScriptクエリ(?以降)はそのまま残り、# 以降だけが消えているのが分かると思います。
ハッシュなし URL の場合
removeHash("/path");
// "/path"
removeHash("/path?page=1");
// "/path?page=1"
JavaScript# がないので、そのまま返ってきます。
ブラウザの URL から「実際にハッシュを消す」パターン
history.replaceState と組み合わせる
ブラウザ上で、「アドレスバーの URL からハッシュを消したい」場合は、removeHash と history.replaceState を組み合わせるのが定番です。
function clearLocationHash() {
const current = window.location.href;
const withoutHash = removeHash(current);
window.history.replaceState(null, "", withoutHash);
}
JavaScriptこうすると、
- ページはリロードされない
- アドレスバーの URL だけが「ハッシュなし」に書き換わる
という挙動になります。
例えば、https://example.com/docs#section-3 に飛んできて、
スクロール処理などが終わったあとに clearLocationHash() を呼べば、
URL だけが https://example.com/docs に戻ります。
「ハッシュ削除」を設計としてどう位置づけるか
ハッシュは「フロント側の一時的な状態」と割り切る
ハッシュはサーバーに送られないので、
「一時的な状態」や「ページ内の位置」を表すのに向いています。
例えば、
#section-3… ページ内の見出し位置#modal=login… モーダルが開いている状態#tab=profile… どのタブが選択されているか
などです。
処理が終わったあとに「もうこの状態は URL に残さなくていい」と判断したら、removeHash を使って URL をクリーンにしておくと、ユーザーにも優しいです。
「クエリ」と「ハッシュ」をきちんと分ける
クエリ削除のときと同じですが、
クエリ(?以降)とハッシュ(#以降)は役割が違うので、混ぜない方がきれいです。
- サーバーに渡す条件 → クエリ
- フロントだけの状態 → ハッシュ
「ハッシュ削除」は、あくまで後者だけを対象にするユーティリティです。
クエリには一切触れない、というのが重要な設計ポイントです。
ちょっとだけ手を動かしてみる
コンソールで、次の順番で試してみてください。
removeHash("https://example.com/docs?page=2#section-3");
removeHash("/path#top");
removeHash("/path?page=1");
const current = window.location.href;
removeHash(current);
JavaScript「どこまでが残って、どこからが消えるか」を、自分の目で確認してみてください。
そのうえで、自分のプロジェクトに
export function removeHash(url) { ... }
export function clearLocationHash() { ... }
JavaScriptのような関数を置いて、
- 文字列としての URL をクリーンにしたい →
removeHash - 実際のブラウザ URL からハッシュを消したい →
clearLocationHash
という使い分けをルール化してみてください。
それだけで、あなたの「ハッシュ削除」は、
場当たり的な url.split("#")[0] から、
意図と再利用性を備えた“業務レベルの URL ハッシュユーティリティ”に一段レベルアップします。
