URL末尾のスラッシュ有無を1つに統一する手順
https://example.com/service と https://example.com/service/。この2つが両方とも同じページを表示する状態になっているサイトは、決して珍しくありません。CMSの設定変更、サーバー移設、フレームワークの乗り換え——きっかけはいろいろですが、気づくと片方だけがリンクされていたり、サイトマップとは違う形式のURLが検索結果に出ていたりします。
この記事は、自社サイトを自分で直す立場のエンジニア/サイト運用担当の方に向けて、末尾スラッシュ(URLの一番うしろに付く「/」のこと)の有無をどう扱うべきかと、実際に片方へ統一しきるまでの手順を、/service の例を1回通してみせながら整理します。
末尾スラッシュのあり・なしは、Googleにとって別々のURLです
まず前提を1つ確定させます。Google 検索セントラルの公式ブログ「To slash or not to slash」は、末尾スラッシュが付いているURLと付いていないURLを、Googleは別々のものとして扱うと明記しています。しかもこれは、そのURLがファイルを指すのかディレクトリを指すのかという区別に関係なくそうなる、とされています。
ここが誤解の多いところです。慣習としては、末尾にスラッシュが付いたURLはディレクトリを、付いていないURLはファイルを指すことが一般的だ——と同じ記事も説明しています。しかし「慣習としてそう読める」ことと「検索エンジンが同一視してくれる」ことは別の話です。公式ブログが述べているのは、ファイルを指すのかディレクトリを指すのかにかかわらず、末尾スラッシュのあり・なしは別々のURLとして扱われる、というところまでです。
そのうえで公式ブログは、両方のバージョンに同じ内容があること自体は許容される(acceptable)が、それが重複コンテンツの問題を引き起こす可能性がある、とも書いています。つまり「両方開ける=即アウト」ではありません。ここを取り違えると、緊急でもない作業に休日を溶かすことになります。
何が困るのか:シグナルが2つのURLに分かれる
では実際に何が問題なのでしょうか。「重複した URL を統合する」のドキュメントは、正規化(複数の似たURLから、検索エンジンに登録させたい代表URLを1つに決めて伝えること)の目的の1つとして、個々のURLが持つシグナル(そのURLへのリンクなど)を、1つの優先URLに統合できるようにすることを挙げています。
逆に言えば、統合が効かないままだと、/serviceと/service/に分かれたリンクの評価が1本にまとまらない可能性が残ります。なお同じドキュメントは、正規URLを指定しなかった場合、Googleがどのバージョンを検索結果に出すのが客観的に最良かを判断するとも説明しています。判断してもらえること自体はありがたいのですが、それは「どちらが選ばれるかをこちらで決めない」ということでもあります。
また「URL の正規化とは」のドキュメントは、正規化とは重複コンテンツの代表URLを選ぶ処理であり、Googleは最も完全で有用なページを正規URLとして選び、そのページをより定期的にインデックスすると説明しています。どちらのURLが選ばれるかで、更新の拾われ方も変わりうる、というわけです。
手順:/service と /service/ を1つに寄せる5ステップ
公式ブログが示している対処は、要点だけ抜き出すとこうなります。1つのURLスタイルを選び、内部リンクとサイトマップで一貫してそれを使い、もう一方は301リダイレクト(恒久的な転送)または rel="canonical" タグで寄せる。この骨格に沿って、実務の順番に並べ直します。
- 現状を実測する。 推測せず、両方のURLが実際に何を返しているかをコマンドで確認します。
curl -sI https://example.com/serviceとcurl -sI https://example.com/service/を叩き、1行目のHTTP/2 200やHTTP/2 301と、301ならlocation:ヘッダーの転送先を見ます。ブラウザの開発者ツールの「ネットワーク」タブでも同じ情報(ステータスコードと転送先)が読めます。 - 優先URLを決める。 後述の判断表に当てはめて、スラッシュあり/なしのどちらを正とするかをサイト全体で1つに決めます。ここで「トップ配下はなし、ブログ配下はあり」のように混ぜると、以降の全工程が二重管理になります。
- サーバーまたはフレームワークで301を設定する。 Apacheなら
.htaccessのリライトルール、nginxならreturn 301、Next.jsならnext.configのtrailingSlash設定というように、実装は環境によって違います。共通して確認すべきなのは「転送が1回で終わること」です。/service/→/service/(自分自身)や、2回3回と連鎖する転送になっていないかを、次のステップで必ず実測します。 - 内部リンクとサイトマップを優先URL側にそろえる。 公式ブログが「内部リンクとサイトマップで一貫して使う」と明示しているのはこの工程です。リダイレクトを置いただけで内部リンクが旧形式のままだと、クローラーも利用者も毎回1段よけいな転送を踏みます。XMLサイトマップに載せるURLも優先URL側だけにします。
- 再測定して、しばらく監視する。 ステップ1と同じコマンドをもう一度叩き、期待どおりになったかを確かめます。公式ブログは設定後の検証として、Fetch as Googlebot で確認することと、ウェブサーバーのログでクロールエラーを確認することを挙げています。手元での確認は、ステップ1で使った
curl -sIをそのまま再実行するのがいちばん手早い方法です。
合格ラインの読み方
ステップ1と5で見るべき「正解の形」は、公式ブログがそのまま書いています。https://example.com/foo/ と https://example.com/foo が期待どおりに動いているか確認したうえで、優先したバージョンはステータスコード200を返し、重複しているほうのURLは優先URLへ301でリダイレクトする——これが合格の形です。判定に迷う余地がないので、そのまま点検項目にできます。
ワークスルー:実際に /service で1回通してみる
架空のサイトで、実際の作業を1周してみます。
ステップ1(実測)。 curl -sI https://example.com/service が HTTP/2 200、curl -sI https://example.com/service/ も HTTP/2 200 を返しました。どちらも200ということは、転送は一切設定されておらず、同じ内容が2つのURLで開ける状態です。まさに今回の対象です。
ステップ2(優先URLの決定)。 サイトマップを開くと、登録されているのは全ページ末尾スラッシュなしの形式でした。主要ページに張られている外部からのリンクも、確認できた範囲ではスラッシュなしが中心です。そこでスラッシュなし(/service)を優先と決めます。
ステップ3(301の設定)。 サーバー側で「末尾スラッシュ付きでアクセスされたら、スラッシュなしへ301」というルールを1本入れます。
ステップ4(そろえる)。 サイト内のhrefを検索し、/service/ の形式で書かれている内部リンクを /service に置換します。サイトマップは元からスラッシュなしなので変更不要でした。
ステップ5(再測定)。 もう一度 curl -sI を叩くと、/service は HTTP/2 200、/service/ は HTTP/2 301 で location: https://example.com/service を返すようになりました。前節の「合格の形」と一致します。ここで作業は完了、あとはサーバーログにクロールエラーが増えていないかを数日みる、という流れです。
所要時間としては、ステップ1〜2は数分、時間がかかるのはステップ4の内部リンク置換です。ページ数が多いサイトほど、ここを飛ばして「リダイレクトを置いたから終わり」にしがちなので、作業見積もりはステップ4を中心に取るのが現実的です。
優先URLの選び方(判断表)
どちらを優先URLにするかで検索上の有利・不利が決まる、という判断材料は公式ドキュメントの記述からは出てきません。そこで実務としては「移行コストが小さいほうを選ぶ」のが合理的です。次の順に見ていくと、ほとんどのサイトで答えが1つに決まります。
| 見るところ | 判断のしかた | つまずきやすい点 |
|---|---|---|
| 現在のサイトマップ | 登録済みURLの形式に合わせる | 生成ツールの設定を変えると全URLが一括で変わるので、変更するなら先に変える |
| 外部から張られているリンク | 数が多いほうの形式に寄せる | 転送は設定するので致命傷ではない。判断が割れたときの決め手として使う |
| CMS・フレームワークの既定 | 既定に逆らわない形式を選ぶ | 既定に逆らうと、更新のたびに設定が戻る事故が起きる |
| 既存の転送設定 | すでに片方向の転送があるならその向きを維持 | 向きを反転させると、旧転送との連鎖で2段転送になりやすい |
| 静的ファイルの配信方法 | /service/index.html を配信する構成ならスラッシュありが自然 | ホスティング側の既定挙動と衝突しないか確認する |
上の表で判断が割れた場合は、いちばん上の行(サイトマップ)を優先してください。工程4の作業量が最小になります。
301が置けないときの選択肢と、その強さの違い
サーバー設定に手が入れられない場合もあります。「重複した URL を統合する」のドキュメントは、正規URLを指定する方法としてリダイレクト、rel="canonical" のリンク要素またはHTTPヘッダー、サイトマップへの収録を挙げ、そのうえで強さに差があると説明しています。
| 指定方法 | 公式が示す位置づけ | 使いどころ |
|---|---|---|
| リダイレクト | 最も強い。非推奨化(deprecation)に使う | サーバーやフレームワークに手が入る場合の第一選択 |
rel="canonical"(リンク要素/HTTPヘッダー) | 強いシグナル。HTML/HTML以外のファイルにそれぞれ対応 | HTMLは編集できるがサーバー設定は触れない場合 |
| サイトマップへの収録 | より弱いシグナル | 単独で頼らず、他の方法と併用する |
同じドキュメントは、一貫した絶対URLを使うこと、robots.txt や noindex は(正規化の手段としては)避けること、そして複数の方法を併用すればより強いシグナルになることも述べています。rel="canonical" をHTTPヘッダーで指定する場合も、リンク要素と同じく絶対URLを使う、と明示されています。相対パスで書いてしまうと、まさに末尾スラッシュの解釈次第で指し先がずれるので、ここは素直に従うのが安全です。
CMSを使っていてHTMLを直接編集できない場合についても、同ドキュメントは触れています。WordPress・Wix・Bloggerのようなサービスでは直接HTMLを書き換えられないことがあり、その代わりにCMS側の検索エンジン向け設定を使う、という案内です。自作テーマに手を入れる前に、まず管理画面の設定項目を探すほうが早い、ということになります。
つまずきやすいところ
トップページ(ドメイン直後)はどうなのか。 「https://example.com と https://example.com/ は同じ扱いなのでは?」という疑問はよく出ます。ただし公式ブログが明言しているのは「ファイル扱いかディレクトリ扱いかに関係なく別URL」というところまでで、ドメイン直後だけの特別扱いについては、この記事が根拠にしている公式の記述からは読み取れません。ですので自分のサイトのトップページでも、ステップ1と同じcurl -sIを1回叩いて実測してしまうのが確実です。判断に自信がないところを推測で埋めないための、いちばん安いやり方です。
相対リンクの解決先がずれる。 「URL 構造をシンプルに保つ」のドキュメントは、親を参照する相対リンク(<a href="../../category/stuff"> のような書き方)を誤ったページに置くと、存在しないページに対してサーバーが正しいHTTPステータスコードを返さない場合に、無限に広がるURL空間(infinite spaces)を作ってしまう可能性があると警告しています。末尾スラッシュの有無は相対リンクの基準位置に効くところなので、統一作業のついでに相対リンクを絶対パスに直しておくと、この手の事故をまとめて避けられます。存在しないURLに対して正しい応答を返せているかどうかは、ソフト404の直し方 の観点と同じ話です。
「両方200のまま」で止めない。 前述のとおり両方に同じ内容があること自体は許容される、と公式ブログは書いています。ですが、どちらを正とするかを自分で明示しないままだと、どのURLが検索結果に出るかの決定をGoogle側の判断に委ねることになります。緊急ではないが、いずれやる——という優先度の付け方が妥当です。
URL構造そのものを複雑にしない。 同じ「URL 構造をシンプルに保つ」は、シンプルなURL構造を作ることを推奨し、読者の言語で分かりやすい単語を使うこと、非ASCII文字にはUTF-8エンコードを使うことを挙げています。末尾スラッシュを統一するタイミングは、不要なパラメータや冗長な階層を見直す機会でもあります。
自己点検チェックリスト
作業後、以下がすべて「はい」になっていれば統一は完了しています。
| 点検項目 | 確認方法 | 合格ライン |
|---|---|---|
| 優先URLが200を返す | curl -sI <優先URL> | ステータス200 |
| 重複URLが優先URLへ301 | curl -sI <重複URL> | 301かつlocationが優先URL |
| 転送が1回で終わる | curl -sIL で転送の連鎖を確認 | 中間ホップなし |
| 内部リンクが優先形式 | ソース内のhrefを全文検索 | 旧形式の残存ゼロ |
| サイトマップが優先形式 | XMLサイトマップを開いて確認 | 旧形式の残存ゼロ |
| クロールエラーが増えていない | ウェブサーバーのログを確認 | 統一前と同水準 |
末尾スラッシュの統一は、重複URLを1つに寄せる作業の中でもいちばん機械的に判定できる部類です。同じ「評価を1つのURLに集約する」というテーマを、パラメータ違いやwwwありなしも含めて広く扱ったものは 重複コンテンツとcanonicalの考え方 にまとめています。
出典
