この記事は、自社サイトのSEO・クローラー対応を実測した記録シリーズの1本である。弁護士みつかるの主要ページに、JS非実行のクローラーへ本文を見せるための事前描画(プリレンダリング)を入れたところ、デプロイは成功しているのに本番だけ結果が変わらない事故が起きた。何を切り分けて真因にたどり着いたかを記録する。
この記事で分かること
- デプロイ別のプレビューURLでは直っていたのに、本番だけ直らなかった理由
- CDNキャッシュ・UA依存・API失敗・Workerルートという4つの候補をどう外したか
- 「一部のページだけ直っている」ように見えた理由と、見分け方・直し方
この記事で分からないこと(正直に書く)
- 真因が残っていた期間、実際にクローラーが古い13字のページを何回取得したか(サーバーログを遡っていないため)
事前描画を入れたのに、本番だけ13字のまま変わらなかった
弁護士一覧ページと専門分野別ページに、JS非実行のクローラーへ本文を見せる事前描画の修正をデプロイした。デプロイ別のプレビューURLでは弁護士一覧が1,634字、専門分野別ページが1,551字と、修正どおりの本文が返ってきた。ところが本番URLでは弁護士一覧が13字、専門分野別ページが21字のまま変わらなかった。同じデプロイIDであることはAPIで確認済みで、コードは同一のはずだった(出所: 自社の運用記録、確認日2026-09-06)。
4つの候補を順に外していった
CDNキャッシュ・UA依存・API失敗・Workerルートの4つを順に疑い、いずれも外れた。CDNはcf-cache-statusがDYNAMICのままでパージも実行済み。UAはGooglebot・GPTBot・ClaudeBot・curlの4種とも同じ結果。クエリ文字列でのキャッシュ回避もランダム値を付けて試したが変わらず。APIは本番上に一時的な診断口を置いて実行し、一覧・詳細とも200でデータが返り、専門分野メタ情報の取得関数もbodyLen 3,938の正常応答だった。Workerのルート設定も専用ドメインの1本だけで無関係だった(出所: 自社の運用記録、確認日2026-09-06)。関数もAPIも正常なのに、返るページだけが古かった。
真因はWorker自身が持っていたキャッシュだった
真因は、ミドルウェア自身がCloudflare WorkerのCache API(caches.default)にHTMLを自前で保存していたことだった。キャッシュキーはoriginとpathnameだけで、クエリ文字列を含まず、TTLは3600秒。ゾーンのpurge_everythingはCDNのHTTPキャッシュを消すものであり、Worker自身が保持するCache APIのエントリまでは消えない。cf-cache-statusがDYNAMICのままだったのも、Workerが動的に生成したように見えるためで、キャッシュヒットを示していなかった(出所: 自社の運用記録、確認日2026-09-06)。
古いHTMLが残っていたのは、修正前に実測のために一度触っていた3ページだけだった。修正後に初めてアクセスした別の分野のページは、最初から新しい本文でキャッシュされ正しく表示されていた。「一部だけ直っている」ように見えた正体は、直した順ではなくキャッシュに触れた順だった(出所: 自社の運用記録、確認日2026-09-06)。
なぜ切り分けに時間がかかったか
弁護士みつかるでは、以前にも人間の目に見えているものと機械的な取得結果が食い違う事故が起きている。人間のブラウザでは本文が0字だったページを、curlの結果だけで「本文はあるがCTAが無い」と誤診し、3ヶ月以上気づかなかった記録である(出所: 自社の運用記録、確認日2026-09-06)。今回はその逆に近く、検証に使った経路(プレビューURL)と実際にクローラーが通る経路(本番URL・Worker自身のキャッシュ)が一致していなかった。Googleも、クロールとレンダリングとインデックスは別々の待ち行列で進み、ページが今どの段階で止まっているかは外から分かりにくいと説明している(出所: Google Search Central「Understand JavaScript SEO basics」https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics、確認日2026-09-06)。
見分け方と直し方
見分けるにはx-edge-cacheヘッダを見る。ただしHEADリクエストでは付かない(GETが条件)ので、curl -s -D-でGET取得して確認する。直し方は、キャッシュキーにバージョン文字列を含め、HTMLを変えたらバージョンを上げて保存し直す方式にし、TTLも600秒に短縮した(出所: 自社の運用記録、確認日2026-09-06)。デプロイ別URLと本番URLで結果が食い違い、同じデプロイIDが確認できている場合は、経路上の自前キャッシュを疑うのが再発防止の要点である。
事前描画やクローラー対応の設計について相談したい場合は、お問い合わせから編集部まで連絡してほしい。noindexの外し忘れについては修正したのにnoindexが残っていた記事、sitemapの転送問題はsitemapに転送先URLを載せていた記事にまとめている。
よくある質問
Q1. デプロイ別URLでは直っていたのに、なぜ本番だけ直らなかったのか
ミドルウェアが自前でCloudflare WorkerのCache API(caches.default)にHTMLを保存しており、ゾーン全体のパージでは消えなかったため。デプロイ別URLは新規のキャッシュ状態から始まるので、修正どおりの本文が返っていた。
Q2. cf-cache-statusがDYNAMICなのに、なぜキャッシュが疑われたのか
cf-cache-statusはCDNのHTTPキャッシュの状態を示すヘッダで、Worker自身が保持するCache APIのヒットは反映されない。ヘッダだけを見て「キャッシュではない」と判断すると見落とす。
Q3. 「一部のページだけ直っている」ように見えたのはなぜか
修正前に実測のために触っていたページだけが古い本文でキャッシュされ、修正後に初めてアクセスしたページは最初から新しい本文でキャッシュされていた。直った順ではなく、キャッシュに触れた順だった。
Q4. 同じ事故を防ぐには何を確認すればよいか
デプロイ別URLと本番URLで結果が食い違い、同じデプロイIDであることが確認できている場合は、経路上の自前キャッシュ(Cache API)を疑う。確認にはx-edge-cacheヘッダをGETリクエストで見る。