URLの大文字・小文字が混在するときの統一手順
/About でも /about でも同じページが開く。サイトマップには小文字で載せたのに、検索結果には大文字のURLが出ている。——原因は、Googleが大文字と小文字を別々のURLとして扱うことです。
Googleは公式に、検索のURL処理は大文字・小文字を区別すると説明しています。例として /APPLE と /apple は、それぞれ固有の内容を持つ別のURLとして扱われます。サーバー側が両者を同じページとして返していても、Googleから見れば「同じ内容のページが2つある」状態です。
答えは単純です。URLの表記を1つに決め、そこへ301リダイレクトで寄せる。Googleも、サーバーが大文字と小文字を同じものとして扱う場合は、すべての文字を同じ表記に揃えることを案内しています。ただし順番があります。現状の実測が先で、リダイレクト、canonical、内部リンクの順に揃えます。
なぜ「別のURL」だと困るのか
同じ内容が複数のURLで開ける状態を、Googleは「重複」として扱います。Googleの説明では、重複した内容から代表となる1つのURLを選ぶ処理を正規化(canonicalization)と呼びます。正規化とは、検索エンジンに「本命として登録してほしいURL」を1つに絞って伝えることです。
ここで起きるのは、選別です。Googleは、重複の中からもっとも完全で有用と判断したページを正規URLとして選び、そちらをより定期的にインデックスします。選ばれなかった重複側は、サイトの巡回負荷を減らすために巡回頻度が下がります。
つまり、担当者が「小文字を本命にしたい」と思っていても、Googleが大文字側を正規に選ぶことがあります。その場合、検索結果に大文字のURLが出ることになります。外部サイトから大文字URLと小文字URLの両方にリンクが張られていれば、リンクによる評価も2つのURLに分かれて扱われる可能性があります。どちらを正規に選ぶかはGoogle側の判断なので、こちらから明確な合図を出す必要があります。
Googleは、重複ページが生まれる原因として地域や端末の違い、通信方式(HTTP/HTTPS)の違い、サイトの機能、そして「事故」を挙げています。大文字・小文字の混在は、この事故の典型です。CMSの移行やリンク貼り付けのミスで、誰も意図しないまま増えていきます。
まず現状を実測する
対策の前に、自社サイトで本当に混在が起きているかを確かめます。思い込みで設定を変えると、かえって転送ループを作ることがあるからです。
- 代表的なURLを大文字混じりで開く。たとえば
https://example.com/blog/をhttps://example.com/Blog/に書き換えてアクセスします。ブラウザのデベロッパーツール(Networkタブ)で、返ってきたステータスコードを見ます。 - 3通りの結果を分類する。
200で同じページが表示されれば「混在が成立している」状態。301で小文字へ転送されれば対策済み。404なら、サーバーがもともと大文字を別物として扱っており、重複は起きていません。 - 大文字URL側のソースで canonical を確認する。
<link rel="canonical" href="...">が小文字URLを指していれば合図は出ています。大文字のまま自分自身を指していれば、大文字側を本命として伝えていることになります。タグ自体が無ければ、canonicalによる合図は出ていません。 - 検索結果に出ているURLの表記を見る。Search Console の「ページ」レポートや、検索結果で自サイトのURLをいくつか開き、大文字が混じっていないかを目で確認します。
- 内部リンクの表記を洗い出す。サイト内のリンクを抽出し、大文字を含む
hrefが何本あるかを数えます。グローバルナビやフッターに1本あれば、全ページから大文字URLにリンクしていることになります。
サーバーの種類で挙動は変わります。Linux上のApacheやNginxはファイルパスの大文字・小文字を区別するため、大文字URLは 404 になるのがふつうです。一方、Windows系のサーバーやCMSのルーティング設定によっては、どちらでも 200 を返します。手順2で 200 が返る環境だけが、この記事の対象です。
対策の優先順位
やることは3つです。順番が大事で、リダイレクトを先に置かないとcanonicalや内部リンクの修正が効きにくくなります。
| 対策 | 役割 | 優先度 | つまずき所 |
|---|---|---|---|
| 小文字への301リダイレクト | 大文字URLへのアクセスをすべて本命へ転送する | 最優先 | 静的ファイルやクエリ文字列まで小文字化すると壊れることがある |
| rel="canonical" を小文字URLで統一 | 転送できない場合の合図・転送の補強 | 2番目 | 相対URLや大文字のままの自己参照は合図として弱い |
| 内部リンク・サイトマップの表記統一 | 新たな大文字URLを生まないようにする | 3番目 | テンプレート由来の1本を見落とすと全ページに波及する |
一つめのリダイレクトは、さきほどの実測で 200 が返った大文字URLを、すべて小文字側に 301 で送る設定です。Googleの正規化の説明でも、リダイレクトは正規URLを決める要素の1つとして挙げられています。
二つめのcanonicalは、Googleが正規化の要素として挙げる rel="canonical" の注釈です。Googleは、rel="canonical" には絶対URLを使うよう案内しています。/about ではなく https://example.com/about の形で、かつ小文字で書きます。
三つめは予防です。サイトマップに載せたURLは、Googleに対する「こちらを正規として提案する」という合図になります。サイトマップと内部リンクが小文字で揃っていれば、合図が一致し、Googleの判断がぶれにくくなります。
ワークスルー:/Blog/Detail/ を /blog/detail/ に寄せる
実際に、https://example.com/Blog/Detail/ が 200 を返していたケースで手順を通してみます。
Apache(.htaccess)の場合。大文字を含むパスだけを対象に、小文字へ転送します。RewriteMap が使えるサーバーなら、次のような書き方になります。
RewriteEngine On
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} [A-Z]
RewriteCond %{REQUEST_URI} !\.(jpg|png|gif|css|js|pdf)$ [NC]
RewriteRule ^(.*)$ ${lc:$1} [R=301,L]
RewriteMap はサーバー設定(httpd.conf や VirtualHost)側でしか宣言できないことがあります。共有サーバーで .htaccess しか触れない場合は、対象URLを列挙して個別に Redirect 301 を書くほうが確実です。
Nginx の場合。location の条件に大文字を含む正規表現を使い、小文字化して転送します。Nginx単体では小文字化の関数が無いため、lua モジュールが使えない環境では、やはり対象URLを列挙する形になります。
location ~ [A-Z] {
rewrite ^(.*)$ /blog/detail/ permanent;
}
上の例は説明用で、実際には対象URLごとに書き分けます。
設定後の確認。/Blog/Detail/ を開いて 301 が返り、/blog/detail/ に着地することを見ます。次に /blog/detail/ のソースを開き、canonical が https://example.com/blog/detail/ になっていることを確認します。最後に、サイト内の href="/Blog/Detail/" を href="/blog/detail/" に置き換えます。
ここで1つ落とし穴があります。画像やCSSのファイル名に大文字が含まれている場合、パス全体を小文字化する設定だと読み込みが壊れます。上の .htaccess 例で拡張子を除外しているのはそのためです。除外の必要があるかは、手順1の実測でファイル単位にも確かめてください。
よくある誤解:canonicalだけで足りる?
「リダイレクトは面倒だから canonical だけ書いておく」。これは、実務でよく選ばれる妥協です。ただし、canonicalは正規化の要素の1つであって、命令ではありません。Googleは複数の要素を組み合わせて正規URLを選ぶため、大文字URLが 200 で開き、外部からのリンクも大文字に集まっていれば、canonicalの合図だけでは小文字に寄らないことがあります。
逆に、リダイレクトを置いたのにcanonicalが大文字のまま自分自身を指している、というちぐはぐも起きます。転送先のページが「本命は大文字です」と言っているわけで、合図が矛盾します。3つの対策は別々ではなく、同じ方向を向かせて初めて効きます。
もう1つ。リンクの書き方が原因で大文字URLが増え続けることがあります。Googleは、親相対のリンク(../../category/stuff のような書き方)が存在しないURLを生む例を示し、ルート相対のURL(/category/stuff)を使うよう案内しています。大文字混在も同じで、テンプレートの中に /Blog/ と書かれた1本があれば、その1本が何千ページ分の大文字リンクになります。リンクの「書き方のルール」まで直して、初めて再発が止まります。
自己点検チェックリスト
作業が終わったら、次の表で1つずつ確かめます。すべて「はい」になれば、Googleへの合図は揃っています。
| 確認項目 | 見る場所 | 「はい」の条件 |
|---|---|---|
| 大文字URLが301で小文字に転送される | デベロッパーツールのNetworkタブ | ステータスが301で、着地先が小文字 |
| 転送ループが無い | 同上 | 転送が1回で止まる |
| canonicalが絶対URLかつ小文字 | ページのソース | https:// から始まり、大文字を含まない |
| サイトマップのURLがすべて小文字 | sitemap.xml | 大文字を含む <loc> が0件 |
| 内部リンクに大文字が残っていない | サイト内リンクの抽出結果 | 大文字を含む href が0本 |
| 画像・CSSが壊れていない | 転送設定後の各ページ | 表示崩れ・404が無い |
反映のあとは、Search Console の「ページ」レポートで、重複や正規ページの選択に関する理由に分類されたURLの件数を追います。Googleが重複側を巡回し直して判断を更新するまでには時間がかかることがあるため、数日で件数が動かなくても、設定が間違っているとは限りません。まずは手順2の実測が 301 になっていることを、設定の正しさの判定基準にしてください。
Wemiroでの確認
Wemiroでは、Search Console のページ別データをURLの表記ごとに並べて見られるため、同じパスの大文字版と小文字版がそれぞれ表示回数を持っているかを確認できます。両方に表示回数があれば混在が成立している合図です。対策後は、大文字側の表示回数が減り、小文字側に寄っていくかを追うと、転送の効きを確かめられます。
URLの表記ゆれは、末尾スラッシュの有無でも同じ構図で起きます。そちらの統一手順は URL末尾のスラッシュ有無を1つに統一する手順 にまとめています。canonicalを書いたのにGoogleに無視される場合は canonicalが無視される原因 も合わせて確認してください。
出典
