URL フラグメント (Fragment Identifier、ハッシュ) とは、URL の「#」記号以降の部分のことです。たとえば「https://example.com/page#section2」の「#section2」がフラグメントです。ブラウザはフラグメントを使って、ページ内の特定の要素 (id 属性が一致する要素) まで自動的にスクロールします。RFC 3986 の 3.5 節はフラグメントを、取得したリソースの内側にある二次的なリソースを間接的に指し示すものと定義しており、その意味の解釈は対象のメディア型に依存するとしています。HTML で id が一致する要素まで移動するのも、この解釈にあたります。id が付いていない箇所を指したい場合には、#:~:text= のあとに本文の文字列そのものを書くテキストフラグメントという書き方もあります。ただしこれは利用者の操作による遷移でのみ働き、対応していないブラウザや、指定した文字列が本文に見つからない場合は、フラグメント全体が無視されてページの先頭が開かれます。
フラグメントの重要な特性として、サーバーには送信されないという点があります。ブラウザが「https://example.com/page#section2」にアクセスする際、サーバーに送られるリクエストは「https://example.com/page」のみで、「#section2」はブラウザ側でのみ処理されます。
この特性は短縮 URL の扱いにも関わりますが、フラグメントが失われるとは限りません。HTTP の仕様 (RFC 9110 の 10.2.2 節) は、リダイレクト応答の Location にフラグメントが含まれていない場合、利用者エージェントは元の参照のフラグメントを引き継いだものとしてリダイレクトを処理しなければならないと定めています。つまり「https://example.com/abc#section2」を開いたとき、サーバーが受け取るのは「/abc」だけですが、ブラウザは転送先に「#section2」を引き継ぎます。引き継がれないのは転送先の URL 自身がフラグメントを持っている場合で、そのときは転送先のフラグメントが優先されます。もう一つ注意したいのは、フラグメントが元のリンクから別のサイトへそのまま渡る点です。同じ仕様の 17.11 節は、これが一方のサイトのフラグメントを別のサイトへ開示する結果になり得るとして、フラグメントに個人に関わる情報を入れているなら、他サイトへのリダイレクトでは (空でもよい) フラグメント部分を付けて引き継ぎを止めるべきだとしています。なお、元の URL にフラグメントを含めて短縮する場合は、保存の時点でその部分を切り落とすサービスもあるため、生成後に実際に開いて確かめるのが確実です。
SPA (Single Page Application) では、フラグメントがルーティングに使われることがあります。「https://app.example.com/#/dashboard」「https://app.example.com/#/settings」のように、フラグメントでページの状態を管理するハッシュルーティングです。この書き方はサーバー側の設定なしで動く手軽さがありますが、Google の URL 構造に関するガイドは、Google 検索は URL のフラグメントを基本的にサポートしていないとして、ページの内容を切り替える目的でフラグメントを使わず History API を使うよう勧めています。JavaScript の SEO に関する文書でも、フラグメントで内容を読み込むハッシュ形式のナビゲーションは避けるべき書き方として挙げられています。History API を使ったパスベースのルーティング (/dashboard、/settings) にする場合は、どの URL で直接開かれてもアプリを返すよう、サーバー側の設定が必要です。
SEO の観点では、フラグメントの違いで内容を切り替える設計は避けるのが無難です。前述のとおり Google は検索が URL のフラグメントを基本的にサポートしないと明言しているため、「example.com/page」と「example.com/page#section2」を別々のページとして扱わせることは期待できません。ページ内の特定セクションを検索結果で独立して扱わせたい場合は、フラグメントではなく別の URL (サブページ) として設計します。