自作サイトでハマった「末尾スラッシュ」の話 — canonical との噛み合わせ
このブログを自分で作っていて、地味だけれど気づきにくいバグにハマりました。
原因は、URL の末尾に付く「/(スラッシュ)」ひとつです。
たったそれだけで、検索エンジンから見たページが二重になりかけていました。
同じ落とし穴は、多くの自作サイトに潜んでいます。 専門用語はかみくだくので、コードが苦手でも読み進められます。
末尾スラッシュって何?
まず、次の 2 つの URL を見てください。
https://example.com/blog/hello
https://example.com/blog/hello/
最後に / が付いているかどうか、それだけの違いです。
人間の目には、同じページに見えます。
実際、ブラウザで開けば、どちらも同じ内容が表示されます。
ところが、検索エンジンにとっては「別々の URL」に見えることがあります。 ここが、今回のつまずきの入り口でした。
canonical タグって何?
こうした「同じ内容が複数の URL で見えてしまう」問題に備える印が、canonical(カノニカル)タグです。
ページの <head> に、こう書きます。
<link rel="canonical" href="https://example.com/blog/hello/" />
意味はシンプルです。 「このページの正式な URL は、これですよ」と検索エンジンに伝えるためのものです。 似た URL が複数あっても、canonical が指す 1 つに評価をまとめてくれます。
何が「噛み合わない」と、まずいのか
問題は、この canonical とサイトの他の部分が食い違うときに起きます。
たとえば、こういう状態です。
- canonical は末尾スラッシュあり(
/blog/hello/)を指している - でも、サイト内のリンクやサイトマップは末尾スラッシュなし(
/blog/hello)で書かれている
すると検索エンジンは、こう迷います。
「リンクは /blog/hello、でも本人は /blog/hello/ が正式だと言っている。どっちを登録すればいい?」
この食い違いが続くと、インデックス(検索結果への登録)が割れたり、遅れたりします。 私の場合は、とくに Bing でうまく登録されない状態が起きていました。
なぜ気づきにくいのか
いちばんやっかいなのは、見た目では気づけないことです。
ブラウザで両方の URL を開くと、どちらも普通に表示されます。 サーバーが片方へ自動でリダイレクトしてくれることも多く、人間には「同じページ」にしか見えません。 だから、目視のチェックでは、まず見逃します。
検索エンジンだけが、URL の形の違いに厳密なのです。 人には同じ、機械には別。 このズレが、落とし穴になります。
どう直すか — URL の形を 1 つに統一する
直し方の芯は、ひとつだけです。 サイト全体で、URL の形を 1 つに統一すること。
具体的には、次の 3 つを同じ形にそろえます。
- canonical タグ
- サイトマップ(sitemap)
- サイト内のすべての内部リンク
そのうえで、サーバー側で「片方の形にリダイレクト」しておけば万全です。
このブログは Astro というフレームワークで作っているので、設定ファイルに一行足して「末尾スラッシュあり」に統一しました。
// astro.config.mjs
export default defineConfig({
site: 'https://example.com',
trailingSlash: 'always', // 末尾スラッシュを必須の形にする
});
配信先の Cloudflare Pages 側も、スラッシュ無しでアクセスされたら、自動でスラッシュ有りへリダイレクトしてくれます。 これで、入り口・案内・正式 URL のすべてが「末尾スラッシュあり」で一致しました。
確認のしかた
直したら、必ず「本当にそろっているか」を確かめます。 私は、ビルドした成果物を検索して、末尾スラッシュ無しのリンクが残っていないかを見ました。
# canonical の形を確認する
grep -r 'rel="canonical"' dist/
# 内部リンクの末尾スラッシュがそろっているか
grep -rE 'href="/blog[^"/]*"' dist/
2 つ目のコマンドで何もヒットしなければ、末尾スラッシュ無しの内部リンクはゼロ、ということです。 canonical・サイトマップ・内部リンクが同じ形になっていれば、合格です。
「あり」と「なし」、どっちに統一する?
ここでよくある疑問が、「末尾スラッシュは、あり・なしのどちらに統一すべき?」です。
結論を言うと、どちらでも構いません。大事なのは、サイト全体で片方に統一することです。
強いて言えば、静的サイトはページをフォルダ単位で書き出すことが多く、その場合は「あり」(/blog/hello/)が自然になじみます。
このブログも「あり」で統一しました。
逆に「なし」で通すなら、canonical もサイトマップもリンクも、すべて「なし」でそろえます。
どちらを選んでも、混ぜないことだけが唯一のルールです。
学んだこと
この一件で、いちばん腹落ちしたのは、これです。 派手なコンテンツより先に、URL の正規化という「土台」を固めておくべきだった。
末尾スラッシュは、動かなくなるバグではありません。 ページはちゃんと表示されるので、放っておいても気づきません。 けれど、土台がずれていると、あとからコンテンツを積み上げるほど、検索での損が静かに広がっていきます。
小さな / ひとつ。
けれど、検索から見つけてもらうことを大事にするなら、最初に詰めておく価値のある一文字でした。