
サイトマップの自動更新を1時間ごとに設定していたのに、最後のビルドから7時間経ってもサイトマップは動かず、その間に公開した4記事が検索エンジンから見えない状態になっていました。原因は特定できないまま、まず応急処置をし、そのあとで仕組みそのものを作り替えました。
RE-AIブログのsitemap.xmlとrss.xmlは、Next.jsのISR(revalidate)で定期的に作り直す設定にしていました。ある日、公開済みのはずの記事がサイトマップに載っていないことに気づきました。記事ページ自体は正常に表示されていて、URLを直接開けば読めます。問題はサイトマップだけが古いままだったことです。クローラーはサイトマップを手がかりに記事を見つけるため、ページが存在していても、サイトマップに載っていなければ発見される機会が減ります。
もともとsitemap.xml・rss.xmlは再検証の指定がなく、ビルド時に一度だけ生成されて固定される設定でした。microCMSで記事を公開してもslugを変えても、次のデプロイまでは反映されません。そこでまず、revalidate=3600を指定し、1時間ごとに自動で作り直す設定に変更しました。これで「公開してもサイトマップに載らない」問題は解決したはずでした。
その翌日、最後のビルドから7時間経ってもサイトマップが再生成されておらず、ビルド時点の記事44件のまま配信され続けていることを確認しました。その間にmicroCMSで公開した4記事が、サイトマップに載っていませんでした。記事ページ自体はrevalidate=60で最新化されていたので、読者は普通に記事を読めます。ずれていたのはサイトマップだけでした。
なぜISRの再検証が発火しなかったのかは、外部から確認できる情報だけでは特定できませんでした。ログでアクセスパターンを追う権限がない中で原因究明を続けるより、確実に直せる方法を優先し、その場では手動で再デプロイして対応しました。再デプロイ後は全記事を取り直すため、47件(microCMS 24件+診断結果の転載記事23件)がそろいました。
ここで考え方が変わりました。以前は「revalidateの間隔を短くしておけば十分」と考えていました。しかし今回の件で、時間ベースの自動更新は「いつかは直る」仕組みであって「いつ直るか」を保証するものではないと分かりました。サイトマップのように「公開したら検索エンジンに知らせる」ことが目的の仕組みには、時間を短くするより、公開そのものをきっかけにする方が確実だと考え直しました。
そこで、microCMS側の公開・更新・削除イベントをWebhookで受け取り、その場でsitemap・RSS・ブログ一覧・記事ページのキャッシュを作り直すAPI(/api/revalidate)を実装しました。再生成の対象は、個別のslugではなく「/blog/[slug]」のような動的セグメント単位で指定しています。slugは後から変更できますし、削除イベントでは変更後・削除後の新しいslugが分からないため、URLそのものを当てにいくと取りこぼすと判断したためです。
Webhookの宛先URLは、知っていれば誰でも叩けてしまいます。検証なしで再生成を実行できる状態にすると、無関係な第三者がURLを繰り返し呼び出すだけでビルドを無駄に走らせ、キャッシュを壊し続けることができてしまいます。そのため署名検証を必須にしました。比較にはtimingSafeEqualを使い、応答時間の違いから署名を推測されないようにしています。また、シークレットが設定されていない場合はエラーを返して止まる(503)ようにしました。設定漏れのまま検証をすり抜けて動いてしまう方が、動かないより厄介だと考えたためです。
検証としては、正しい署名では200、署名なし・誤った署名・改ざんされたボディではいずれも401、GET以外を許可しないことを確認しました。署名検証の単体テストを8件追加し、既存分と合わせて706件のテストが通過しています。
今回の件で分かったのは、「更新頻度を上げる」対応と「更新のきっかけを変える」対応は、似ているようで別の問題を解決しているということです。前者は反映までの遅れを縮めますが、反映されない場合の保証にはなりません。後者は、公開という事実そのものに再生成を紐づけるため、遅れそのものが原理的に起きにくくなります。今回はまず前者で様子を見て、それでも起きた問題を後者で塞いだ、という順番になりました。
2点、正直に書きます。1つ目は、最初のrevalidate=3600でなぜ再検証が発火しなかったのか、根本原因は特定できていません。Webhook方式に切り替えたことで同じ症状は起きにくくなりましたが、原因不明のまま別の対策で覆った形です。2つ目は、Webhookを受け取るには本番環境にシークレットを登録し、microCMS側の通知先を設定する必要があり、動作確認はローカルでの署名検証テストまでです。本番での発火まで確認できているかは、この記録の時点では確認できていません。
本番でのWebhook発火を実際のイベントで確認すること、そして今回のように「反映されているはずなのに反映されていない」状態を早期に気づけるよう、サイトマップの記事数と実際の記事数を突き合わせる仕組みを検討しています。
今回の開発日誌と同じ日には、融資AIの過大評価を止めた判断(全額現金で買うと、融資AIが満点をつけていました)や、AI統合コメントの重複を直した記録(統合AIコメントの平均46%が、実は同じ文章になっていました)もあります。あわせて読むと、この時期のRE-AIが「表に出る数字や文章」と「裏側の仕組み」の両方を同時に直していたことが分かると思います。
この記事を書いた人

鈴木基公
RE-AI開発者・不動産投資分析サービス運営者
1件の物件を買うか判断するために、4時間。 場合によっては、答えが出るまで何日もかかる。 その間にも、良い物件は他の投資家に買われていきます。 「分析に時間を使うのではなく、判断に時間を使うべきではないか。」 この疑問から開発したのが「RE-AI」です。 数時間かかっていた分析をAIがサポートし、投資家が本来やるべき『比較・現地調査・意思決定』に時間を使える環境を目指しています。

統合AIコメントの平均46%が、実は同じ文章になっていましたRE-AI開発日誌 #004
2026/8/8

熊本の検証物件で、家賃単価が本来の5分の1になっていました|RE-AI開発日誌 #011
2026/8/12

正直に言うと、良いAIを作れば自然に売れると思っていましたRE-AI開発日誌 #002
2026/7/30

全額現金で買うと、融資AIが満点をつけていましたRE-AI開発日誌 #003
2026/8/1

18日前に直したのと同じ抜け穴が、別のAPIにも残っていました|RE-AI開発日誌 #012
2026/8/13

住所を1文字間違えただけで、査定価格が740万円動いていましたRE-AI開発日誌 #005
2026/8/8

同じ「借入ゼロ」が、シナリオ比較でまた100点を出していました|RE-AI開発日誌 #013
2026/8/14

外部データが揃う前に、AIはコメントを書き始めていました|RE-AI開発日誌 #014
2026/8/17