最終確認日

Next.jsのブログ記事がインデックスされない理由を調査する

環境

こころあたり

  • robots.txt
  • オンデマンドISRを使っているから?
  • リダイレクトをしているせい?

調査

robots.txt の確認

https://uruly.xyz/robots.txt

User-agent: *
Disallow:

Crawl-delay: 3600

問題なし

メタタグnoindex の確認

<meta name="robots" content="noindex">

探したけどない。

canonical の設定が間違えている?

使っていない。

Search Console でURLリクエストしてみる

URL検査をして登録されていないことを確認したあと、インデックス登録をリクエストしてみる。

「このページはURL は Google に登録されています。」になる!

ということは問題はなさそう?

たすけてChatGPT!

コードには問題なさそうで、最も有力なのは Google の「価値評価ロジック」によるスキップらしい。

かなしい。

また、オンデマンドISRは最初のアクセスでページが生成されるので、まだ誰もアクセスしていないページは存在していない扱いになり、クローラーが来なかった。

かなしい。

できそうな対策

改めて(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"

そんな悪いとこなさそう。

なにもうまくいかない…

sitemap.xml の取得に成功した

信じるものは reddit
https://www.reddit.com/r/nextjs/s/TZrY1qZw0H

Next.jsのブログ記事がインデックスされない理由を調査する-1775967146904

末尾に / を追加したら成功した。

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 キャッシュ、または初回再生成時の失敗状態です。

考えられる対応はこのあたりです。

  1. Search Console の再テストをもう一度かける
    初回で再生成が走り、2回目で 200 になるなら、その URL は以後安定する可能性が高いです。

  2. デプロイ後に sitemap の全 URL を一度 warm する
    Google に初回生成を踏ませず、こちらで先に全 canonical URL を curl して 200 にしておく方法です。現状の症状にはかなり効きそうです。

  3. Vercel の Runtime Logs を見る
    Search Console の「1回目」の時刻に、どの例外 digest が出ているか確認したいです。もしまだコード上の例外があるなら、ここに出ます。

  4. 長期的には記事ページの 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 のサイトマップより各エラーを再検証実行しておいた。

サイトアイコン
公開日
更新日