Next.jsのブログ記事がインデックスされない理由を調査する
環境
- Next.js + Vercel
- オンデマンドISR を使っている
- 本番環境は https://uruly.xyz
こころあたり
robots.txt?- オンデマンドISRを使っているから?
- リダイレクトをしているせい?
調査
robots.txt の確認
User-agent: *
Disallow:
Crawl-delay: 3600
問題なし
メタタグnoindex の確認
<meta name="robots" content="noindex">
探したけどない。
canonical の設定が間違えている?
使っていない。
Search Console でURLリクエストしてみる
URL検査をして登録されていないことを確認したあと、インデックス登録をリクエストしてみる。
「このページはURL は Google に登録されています。」になる!
ということは問題はなさそう?
たすけてChatGPT!
コードには問題なさそうで、最も有力なのは Google の「価値評価ロジック」によるスキップらしい。
かなしい。
また、オンデマンドISRは最初のアクセスでページが生成されるので、まだ誰もアクセスしていないページは存在していない扱いになり、クローラーが来なかった。
かなしい。
できそうな対策
- sitemap.xml をつくる
- canonical を設定してみる
- パンくずリストも大事みたい。
- SNSとかにもっとシェアしなさーい!
- コツコツインデックスをリクエストする
改めて(2026年4月)
- 存在しない記事でも 200 を返していた
- loading.tsx が原因だったので外してみた。
- sitemap.ts の場所が悪そうだった
- 直したけど読み込まれず。
- Next.jsブログのISRを改善する(2026年4月)
レスポンスをチェックしてみる。
curl -I -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://uruly.xyz/posts/read-starting-ux-design-in-figma
curl -I -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://uruly.xyz/robots.txt
curl -I -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://uruly.xyz/sitemap.xml
curl -s -o /dev/null -w "code=%{http_code} ttfb=%{time_starttransfer} total=%{time_total}\n" https://uruly.xyz/posts/read-starting-ux-design-in-figma
curl -s -o /dev/null -w "code=%{http_code} ttfb=%{time_starttransfer} total=%{time_total}\n" -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" https://uruly.xyz/posts/read-starting-ux-design-in-figma
curl -s -o /dev/null -w "code=%{http_code} ttfb=%{time_starttransfer} total=%{time_total}\n" "https://uruly.xyz/posts/read-starting-ux-design-in-figma"
そんな悪いとこなさそう。
- https://www.reddit.com/r/nextjs/comments/1bho74f/sitemymap_for_google_search_console/?tl=ja
- https://github.com/vercel/next.js/issues/51649
- ずっとある問題なのかも。
- https://github.com/vercel/next.js/issues/75836
なにもうまくいかない…
sitemap.xml の取得に成功した
信じるものは reddit
https://www.reddit.com/r/nextjs/s/TZrY1qZw0H
末尾に / を追加したら成功した。
app/sitemap.ts で動的に生成しているが、無事に「成功しました」となった。
Supabase上では1,262あるっぽいが、sitemap 上で検出されたページが1,005件名のが気になる。
さらに改めて
2026-05-04
Google Search Consoleであらゆるページが5xxエラーで登録できない。Codexに調査を頼む。
ここで少し変な挙動です。サンプルでは初回 500 だった URL が、直後に見ると x-vercel-cache: PRERENDER の 200 になっています。つまり「初回 ISR 生成のリクエストだけ 500 を返し、その後キャッシュ済み 200 になる」タイプの可能性が高いです。未アクセスっぽい URL を使って、初回ヘッダーを捕まえます。
これの可能性が非常に高い気がする。
根っこは、本番ランタイムで内部 API fetch が失敗した瞬間に fetchWithFallback が throw してページ全体を 500 にしている点です。Google のように sitemap から大量の未キャッシュ URL を踏む相手だと、この一時的な失敗がそのまま Search Console の 5xx になります。ここを「内部 API が落ちたら Supabase 直読みへフォールバック」にして、クロール時の 500 を潰します。
だいぶCodexが自律的に調査してくれている感がある。
本番の sitemap URL を Googlebot UA でサンプリングしたところ、実際に一部ページが 500 を返していました。ただし直後に同じ URL を叩くと 200 になり、x-vercel-cache: PRERENDER になっていました。つまり「未キャッシュ/ISR 初回生成時だけ一時的に 500、その後は表示できる」という挙動です。Search Console が拾っているのはこの初回 500 っぽいです。
対応として、src/libs/fetchWithFallback.ts を修正しました。本番では記事取得時に内部 API を fetch していますが、ここが 500 や一時的なネットワーク失敗を返すとページ全体が 500 になっていました。今は内部 API が失敗した場合、throw せず Supabase 直読みへフォールバックします。
本番環境にデプロイして確認したけどまだ直っておらず。再調査をお願いした。
これは「GSC の表示だけが古い」というより、本番の canonical URL に古い 500 の ISR/Prerender キャッシュが残っていて、初回アクセスで再生成され、2回目に 200 になる挙動に見えます。
こちらで確認したところ:
- sitemap 内の一部 URL は Googlebot UA で実際に 500
- 同じ URL にクエリを付けると 200
- その後 canonical URL も 200 になった
つまり、現在のデプロイ済みコード自体はそのページを描画できています。問題は、URL 単位で残っている 500 の prerender/ISR キャッシュ、または初回再生成時の失敗状態です。
考えられる対応はこのあたりです。
Search Console の再テストをもう一度かける
初回で再生成が走り、2回目で 200 になるなら、その URL は以後安定する可能性が高いです。デプロイ後に sitemap の全 URL を一度 warm する
Google に初回生成を踏ませず、こちらで先に全 canonical URL を curl して 200 にしておく方法です。現状の症状にはかなり効きそうです。Vercel の Runtime Logs を見る
Search Console の「1回目」の時刻に、どの例外 digest が出ているか確認したいです。もしまだコード上の例外があるなら、ここに出ます。長期的には記事ページの ISR 方針を見直す
SEO を優先するなら、記事詳細だけ force-dynamic にして毎回 SSR に寄せる、または build/prewarm で全記事を確実に生成する、という選択肢があります。結論としては、単なる Search Console 側の反映待ちだけではなさそうです。ただし、今見えている 500 は「現在のコードで描画不能」ではなく、古い/未生成の URL キャッシュが初回だけ 500 を返している状態にかなり近いです。まずは sitemap 全 URL の warm を入れるのが一番現実的です。
ふむ。revalidate をした後に組み込むことにした。revalidate 後に一度curlで叩いてエラーを排除しておく。
なんかあまり良い方法って感じはしないけど、暫定的にこれでokにしておく。
と思ったけど動いてないかもしれん。
2026-05-05 Google Search Console のサイトマップより各エラーを再検証実行しておいた。