私は /en/blog/... という構造で約3,000ページを追加し、sitemap を更新しました。その直後、Yandex Webmaster で予想外の挙動に気づきました。Yandex が /en を含まない、対応する /blog/... の URL をクロールしようとしていたのです。
もしそれらの URL がそのまま 404 を返していたら、存在しないパスに対する無駄なクロールが大量に発生していた可能性があります。幸い、私は以前から、言語プレフィックスのないパスを本来の英語 URL に送る 308 リダイレクトを設定していました。
この小さな防御的ルーティングが、想像以上に役立ちました。
実際に確認できたこと
事実として言える流れは次のとおりです。
/en/blog/...形式の新規ページを約3,000件含む sitemap 更新を公開した。- その後、Yandex Webmaster で、対応する
/blog/...URL を Yandex がクロールしようとしていることを確認した。 - それらの代替パスには、すでに 308 リダイレクトを設定していた。
- そのため、リクエストは 404 で終わらず、本来の
/en/blog/...URL に送られた。
ここで、元の記事の表現は修正する必要があります。私は「Yandex が sitemap を誤ってパースした」と証明できたわけではありません。sitemap 更新後に予想外のクロール先を見つけた、という時系列はありますが、それだけで Yandex 内部の原因までは分かりません。検索エンジンが URL を発見する経路は sitemap だけではありません。十分な根拠がない以上、正確に言えるのは「Yandex が私の想定外のパスをクロールした」というところまでです。
この区別は重要です。クローラーが変な URL をリクエストしたことは観測事実です。なぜその URL を選んだのかは、別の主張になります。
308 リダイレクトが効いた理由
私のルーティングでは、短いパスをローカライズ済み URL の恒久的な別名として扱っていました。単純化すると次の形です。
/blog/example-post -> 308 -> /en/blog/example-postそのため、クローラーが予想外の URL に来ても、最終的には私が配信したいページへ到達しました。
308 Permanent Redirect は、リクエストメソッドとボディを維持する恒久リダイレクトです。ただし、検索クローラーの通常の GET リクエストでは、メソッド保持そのものが主目的ではありません。今回重要だったのは「恒久的な移動」であることを明示できる点でした。現在の Yandex Webmaster のドキュメントでも、301 と 308 はどちらも permanent redirect として扱われています。
Yandex Webmaster のリダイレクトに関する公式ドキュメント.
だからといって、SEO では 308 が 301 より常に優れている、という意味ではありません。私の場合はすでに 308 を使っており、それが「想定外 URL を行き止まりにしない」という役割を果たした、というだけです。
リダイレクトは sitemap の修正ではない
リダイレクトは被害を抑えてくれましたが、不要なクロール自体が望ましいわけではありません。リダイレクトが1回増えれば、リクエストも1段増えます。また、広すぎるリダイレクトルールは、URL 生成側のバグを見えにくくすることもあります。
もし sitemap 自体に古い URL やリダイレクト前提の URL が入っているなら、まず sitemap を直し、最終 URL を出すべきです。リダイレクトは、旧 URL、代替 URL、あるいはクローラーが偶然発見した URL を安全に処理するためのものです。雑な sitemap を正当化するためのものではありません。
今回、私の sitemap にはもともと /en/blog/... が入っていました。308 は、クローラーが /blog/... から来た場合の耐性を追加してくれただけです。
同じことが起きたら今は何を確認するか
この件以降、URL 移行や多言語ルーティングでは次を確認するようにしています。
- デプロイ後の sitemap 本体を見る。 生成コードだけを信用せず、実ファイルから複数 URL を抜き出して確認する。
- 最終レスポンスを確認する。 index させたい sitemap URL は、不要なリダイレクトチェーンを挟まず目的のページを返すのが理想です。
- 予測可能な別パスをテストする。 旧 URL や言語プレフィックスなしの URL に恒久的な移動先があるなら、1対1で明示的に対応させる。
- リダイレクトチェーンを避ける。
A -> B -> CよりA -> Cの方が確認しやすい。 - 可能なら Webmaster の表示とサーバー側の情報を照合する。 Webmaster は有用ですが、その URL が最初にどこから発見されたかまで常に分かるわけではありません。
- クロールだけで順位を語らない。 crawling、indexing、ranking、traffic は別の段階です。
代替パスの確認自体は、たとえば次のような最小限のチェックで十分です。
curl -I https://example.com/blog/example-post
HTTP/2 308
location: https://example.com/en/blog/example-postこれは説明用の例ですが、ポイントは同じです。ルールが動くはずだと考えるのではなく、実際の status と Location を確認します。
言えることと言えないこと
私が確認できるのは、事前に設定していた 308 リダイレクトによって、予想外の /blog/... リクエストが 404 で終わらず、本来の URL に到達したことです。
一方で、その原因が Yandex の sitemap parser だったとは確認できません。また、この 308 によって順位が上がった、indexing が改善した、あるいは具体的に何件の traffic を「救った」といった測定もしていません。そこまで言うと、手元の証拠を超えてしまいます。
この経験から残った結論は、もっと限定的です。URL アーキテクチャは、境界で起きる予測可能なミスに耐えられる方がいい。 正しい sitemap が第一の防御線で、正確な恒久リダイレクトが第二の防御線です。
この2つが揃っていれば、クローラーが想定外のパスに来ても、それが大量の dead URL に直結する可能性をかなり下げられます。