WordPressからAstroへ移行したら、存在しないURLがずっと200を返していた話
この記事について
版元が運用する媒体の一つ(以下 ND)を WordPress から Astro へ移行した後、存在しない URL にアクセスするとステータス 200 が返る「ソフト 404」状態になっていたのを見つけた。ページの中身は「見つかりません」的な表示になっていても、HTTP ステータスとしては「正常に存在する」と応答してしまう。検索エンジン側からは実在するページとして扱われかねず、放置するとインデックスの質が下がる。3 ファイル・29 行という小さな変更で直した記録。
何が起きていたか
静的サイトのホスティングは、どのパスにもマッチしないリクエストに対して既定でフォールバック用の HTML を返す設定になっていることが多い。ND でも、存在しないパスにアクセスした際にフォールバックページ自体は表示されるものの、ステータスコードは 200 のままだった。
ページの見た目だけを見て「404 ページはある」と判断すると見落とす。実際に確認すべきは表示内容ではなくレスポンスヘッダのステータスコードで、この 2 つは別物として管理する必要がある。
curl -sI https://example.com/存在しないパス | head -1
# 修正前: HTTP/1.1 200 OK
# 修正後: HTTP/1.1 404 Not Found
対処:専用ページ + ルーティング設定の2本立て
対処は 2 段構えにした。
1) 専用の 404 ページを追加する。 ページ自体には noindex を明示し、検索エンジンにインデックスさせない意図をメタタグでも二重に示す。
<Layout
title="ページが見つからない"
noindex={true}
>
<h1>ここには、何もいなかった。</h1>
<p>お探しのページは見つからなかった。URL を打ち間違えたか、引っ越したか、そもそも最初からいなかったのかもしれない。</p>
</Layout>
2) ルーティング設定にキャッチオールの 404 ルールを追加する。 静的ホスティングの _redirects ファイルに、どの既存ルールにもマッチしなかったパスを 404 ページへ、かつステータス 404 で返す 1 行を追加した。
# 未マッチのパスは 404.html を 404 ステータスで返す
/* /404.html 404
_redirects の評価は上から順に行われるため、移行前の旧 URL から新 URL への 301 リダイレクト群は、このキャッチオールより先に書いてある。個別の 301 ルールが先に評価されるので、この 1 行を足しても既存のリダイレクトには影響しない。
順序を間違えると起きること
このキャッチオール行を 301 リダイレクト群より 前 に置くと、あらゆるパスが最初の行にマッチしてしまい、後続の個別リダイレクトが一切評価されなくなる。旧 URL からの引き継ぎリンクがすべて 404 に落ちる。ルールファイルは「上から順に最初にマッチした行が勝つ」という前提を意識して書く必要があり、キャッチオールは必ず最後に置く。
やってみてわかったこと
- 静的サイト移行では「ページの見た目」と「HTTP ステータスコード」が一致しているかを別々に確認する必要がある。表示だけ見て正常と判断すると、ステータスのズレは検索エンジン経由の巡回でしか気づけない
- リダイレクトルールファイルは記述順が評価順になる。キャッチオールルールは常に最後に置く
- 実装自体は小さくても、検索エンジンのインデックス品質に効いてくる種類の不具合は、気づいた時点でのコストが低いうちに直す価値がある
更新履歴
- 2026-08-06: 初稿公開