AWS Amplifyの既定設定のままだと、存在しないURLが全部200を返す
AWS Amplify にサイトを繋いだら、数分で公開されました。トップページも記事ページも正しく表示されます。ここで「できた」と思って先に進むと、気づかないまま検索評価を削り続ける設定が1つ残ります。
このサイトを公開するときに見つけたので、実害が出る前に直せました。ただ、見つけたのは偶然に近い経緯です。同じ設定は既定で入るので、Amplify で静的サイトを公開した人はまず該当します。
何が起きているか
ブラウザで、自分のサイトの存在しないURLを開いてみてください。
https://あなたのドメイン/このページは存在しません/
404ページではなく、トップページが表示されるはずです。しかもエラーではなく、正常なページとして。
これが問題です。表示が変なのではありません。サーバーが返しているステータスコードが200(正常)になっていることが問題です。
確かめ方
ブラウザの見た目だけでは分かりません。ステータスコードを直接見ます。macOS や Linux のターミナル、Windows なら PowerShell で次を実行します。
curl -o /dev/null -w "%{http_code}\n" https://あなたのドメイン/definitely-not-a-real-page/
返ってきた数字が 200 なら該当します。404 なら問題ありません。
ブラウザの開発者ツールでも確認できます。F12キーを押して「ネットワーク」タブを開いた状態で存在しないURLにアクセスし、一番上のリクエストのステータス欄を見ます。
なぜそうなるのか
Amplify は、アプリを繋いだときに書き換えとリダイレクトのルールを1つ自動で入れます。
| 送信元 | ターゲット | 種類 |
|---|---|---|
/<*> |
/index.html |
200(書き換え) |
/<*> は「どのURLにも一致する」という指定です。つまりあらゆるURLに対して index.html を返す、という設定が既定で入っています。
これは SPA(シングルページアプリケーション)のための設定です。React や Vue で作った、URLの切り替えをJavaScriptが担当するタイプのアプリでは、サーバーは常に同じHTMLを返し、そこから先はブラウザ側が処理します。この構成では、この設定がないと動きません。だから既定で入っています。
問題は、ページごとにHTMLファイルが存在するタイプのサイトでは、これが有害にしかならないことです。Astro、Hugo、Jekyll、Next.js の静的出力、あるいは手書きのHTMLを置いた場合。これらはすべて該当します。
何が問題なのか
存在しないURLが「存在する」ことになる
検索エンジンにとって、ステータスコード200は「このURLには内容がある」という意味です。404は「ここには何もない」です。
既定の設定のままだと、打ち間違えたURL、古いリンク、他サイトからの誤ったリンク、その全部が200を返します。 内容はトップページと同じです。
Google はこれをソフト404と呼びます。Search Console のインデックス作成レポートに「送信されたURLが見つかりませんでした(404)」ではなく「ソフト404」として並びます。
なぜソフト404が悪いのか
- 重複コンテンツになります。 無数のURLが同じ内容(トップページ)を返すので、どれを正規とみなすべきか判断がつかなくなります
- クロール予算が無駄になります。 存在しないページを繰り返し巡回させることになります
- リンク切れが検出できなくなります。 自分のサイト内のリンクを打ち間違えても、404にならないので気づけません
3つ目は運用面でとくに厄介です。ナビゲーションのリンクを1文字間違えても、押せば普通にトップページが出るので、壊れていることに誰も気づきません。
AdSense の審査にも関わります
広告の掲載を申請する場合、内容の薄いページや重複したページは審査でマイナスに働きます。存在しないURLが無数に200を返す状態は、まさにその条件に当てはまります。
直し方
Amplify のコンソールで、catch-all ルールを書き換えます。削除ではなく書き換えです。
- Amplify コンソールでアプリを開く
- 左メニューの「ホスティング」→「書き換えとリダイレクト」
- 既存の
/<*>→/index.html(200)のルールを編集する
変更後はこうします。
| 送信元 | ターゲット | 種類 |
|---|---|---|
/<*> |
/404.html |
404 |
ターゲットを /404.html に、種類を 200 ではなく 404 に変えるのが要点です。
404ページを用意しておく
このルールは 404.html が出力されている前提です。ビルド結果(Astro なら dist/)に 404.html があるか確認してください。
Astro の場合は src/pages/404.astro を置けば生成されます。Hugo なら layouts/404.html、Jekyll なら 404.html です。
直ったか確かめる
反映には少し時間がかかります。数分待ってから、さきほどと同じコマンドを実行します。
curl -o /dev/null -w "%{http_code}\n" https://あなたのドメイン/definitely-not-a-real-page/
404 が返れば完了です。ブラウザでも404ページが表示されるはずですが、見た目が404ページでもステータスが200のまま、という状態があり得るので、必ずコマンドかネットワークタブで数字を確認してください。
すでに公開してしばらく経っている場合
Search Console でインデックス作成レポートを開き、「ソフト404」の項目を確認してください。件数が出ていれば、この設定が原因の可能性が高いです。
設定を直したあとは、Search Console で数日〜数週間かけて再クロールされ、順次解消されます。急ぐ必要はありませんが、放置すると増え続けます。
これはAmplifyだけの話ではありません
同じ構造の設定は、他のホスティングにもあります。
- Netlify:
_redirectsに/* /index.html 200と書くテンプレートが広く出回っています - Cloudflare Pages: 同じく
_redirectsでの指定 - Firebase Hosting:
firebase.jsonのrewrites設定
どれも SPA のためのもので、ページごとにHTMLがあるサイトでは外す必要があります。
AIにサイトを作らせて公開した場合、この設定は「デプロイの手順」としてまとめて入ってきます。動いているので問題があるように見えません。 だからこそ、公開したら一度ステータスコードを確認してみてください。
まとめ
- Amplify は既定で
/<*>→/index.html(200)という SPA 用の設定を入れる - ページごとにHTMLがある静的サイトでは、存在しないURL全部が200を返す状態になる
- Google はこれをソフト404として扱い、重複コンテンツ・クロール予算・リンク切れの検出、いずれにも悪影響が出る
curl -o /dev/null -w "%{http_code}\n" https://ドメイン/存在しないパス/で確認できる- コンソールの「書き換えとリダイレクト」で、
/<*>→/404.htmlの 404 に書き換える - 同じ設定は Netlify、Cloudflare Pages、Firebase Hosting にもある
見た目では気づけません。数字で確認してください。