Headless CMSのSEO
Headless CMSのSEOは、フロントエンドがどのようにレンダリングするかにかかっています。SSG/SSRとCSR、メタデータ、canonical、サイトマップ、ISRの落とし穴、AIクローラー、移行を解説します。
言語
このページには証拠シグナルが1件あります
- 関連するライブツールRaw vs. Rendered HTML Checker
Headless CMSはSEOに良いとも悪いとも限りません。フロントエンドが使うレンダリング方式がすべてを決めます。SSGとSSRは安全な選択肢で、CSRはリスクがあり、ISRには古いコンテンツの落とし穴があります。WordPressプラグインが自動で行っていたメタデータ、サイトマップ、canonical、robots.txtは、明示的に構築する必要があります。レンダリングを正しくし、プレビュー環境をインデックスから外し、放置されたWordPressサイトをHeadless CMSで上回れる状態にします。
要点 — ヘッドレスCMSは、コンテンツを書く場所と表示する場所を分離します。この分離自体はSEO上の問題ではありません。ただし、Webサイト側が検索エンジンに完成済みのHTMLを渡すことが前提です。重要なのは、ページ全体を訪問者のブラウザーでレンダリングする(CSR)のではなく、サーバー上またはビルド時にレンダリングする(SSRまたはSSG)ことです。また、タイトル、サイトマップ、robots.txtなど、WordPressプラグインが代行していたSEO機能は自分たちで実装する必要があります。
「ヘッドレス」とは何か
WordPressのような従来型の構成では、コンテンツを書く場所と、それをWebページに変換する場所は同じシステム内にあります。ヘッドレスCMSは、この2つの役割を分離します。CMSはコンテンツの保管庫(Contentful、Sanity、Strapiなど)になり、Next.js、Nuxt、Astro、Gatsbyなどのフレームワークで構築した別のWebサイトが、そのコンテンツを取得して実際のページを生成します。 Evidence for this claim A headless CMS separates content management from the presentation frontend and exposes content through APIs. Scope: Contentful as a representative headless CMS architecture. Confidence: high · Verified: Contentful: What is a headless CMS?
これがSEOに悪影響を与えるのではないかと心配する人もいますが、ヘッドレスCMSそのものが問題になるわけではありません。バックエンドのCMSは、検索順位にほとんど直接影響しません。重要なのは、フロントエンドがページをどのように生成するかです。
最も重要な判断:レンダリング方式
誰か(またはGooglebot)がページをリクエストしたとき、完成したHTMLはどこで生成されるのでしょうか。基本的には、安全な方法が2つ、リスクのある方法が1つあります。
- ビルド時(SSG) — あらかじめページをプレーンなHTMLファイルとして生成します。高速で、検索エンジンにも適しています。
- リクエストごとにサーバー上で生成(SSR) — サーバーが完全なページを生成して返します。これも検索エンジンに適しており、常に最新の内容を提供できます。
- 訪問者のブラウザー内で生成(CSR) — サーバーはほぼ空のシェルを返し、その後JavaScriptが内容を埋めます。SEOでは最もリスクの高い方法です。
GoogleはJavaScriptを実行できますが、レンダリングは別の処理段階であり、JavaScriptが失敗したりブロックされたりすることもあります。ほかのクローラーはレンダリング能力が異なるため、重要なコンテンツを確実に届けるには、サーバーでレンダリングまたは事前レンダリングしたHTMLが最も汎用的です。 Evidence for this claim Google processes JavaScript through a rendering stage, and blocked or failed resources can prevent expected content from rendering. Scope: Google Search; other crawlers have their own capabilities. Confidence: high · Verified: Google: JavaScript SEO basics
「SEO設定はどこへ行ったのか」という問題
WordPressでは、Yoastのようなプラグインがタイトル、メタディスクリプション、サイトマップ、canonicalタグを自動的に処理していました。ヘッドレスサイトにはそのプラグイン層がありません。そのため、開発者が意図的に次の作業を行う必要があります。
- CMSのコンテンツモデルにSEOフィールド(タイトル、ディスクリプションなど)を追加する。
- それらのフィールドをページのHTMLに組み込む。
- サイトマップとrobots.txtを作成する。
どれも難しい作業ではありませんが、自動では行われません。「ヘッドレスサイトにしたらSEOを失った」という話の多くは、実際には「プラグインが行っていた処理を誰も再実装しなかった」という話です。
気づかないうちに壊れやすい点
- プレビュー/ステージングサイトがインデックス登録される。 ヘッドレス構成では、公開アクセスできるプレビューURLが作られることがよくあります。Googleが見つけると、サイトの重複コピー全体をインデックス登録する可能性があります。これらはインデックス登録を防ぐ必要があります。
- リンクに見えても本物のリンクではない。 検索エンジンがたどるのは、実際の
<a href>リンクだけです。JavaScriptで遷移するクリック可能な<div>はクロールされません。
4つのレンダリング方式の比較、canonicalタグ、サイトマップ、ISRの古いコンテンツ問題、Bing、移行まで含む詳しい内容は、Advancedタブに切り替えてください。
要点 — ヘッドレスSEOでは、アーキテクチャそのものがプロダクトです。CMSバックエンドはSEOにほぼ中立であり、すべてを決めるのはフロントエンドのレンダリング方式です。SSGとSSRは完成済みのHTMLを配信する安全な選択肢で、CSRは最もリスクが高く、ISRには再検証後の最初のリクエストで古い内容を返す落とし穴があります。Yoastが自動処理していたメタデータ、canonical、サイトマップ、robots.txtは明示的に実装する必要があります。canonicalのロジックはCMS → フレームワーク → コンポーネントに分散しやすいため、単一の
SITE_URLを使ってレンダリング層で設定します。同じ役割分担はロケールルーティング/hreflangやプレビューへのアクセスにも当てはまります(まず認証し、noindexはアクセス制御ではなく二次的な防御とする)。Googleは動的レンダリングを非推奨とし、SSR/SSG/ハイドレーションを推奨しています。AIクローラーのレンダリング能力はプロバイダーごとに異なり、公開/非公開イベントではタイマーではなくWebhookでキャッシュをパージする必要があります。
アーキテクチャがプロダクトを決める
ヘッドレスCMSは、コンテンツの保存、コンテンツモデル、編集UI、APIを備えたバックエンドにすぎません。Next.js、Nuxt、Gatsby、Astro、SvelteKit、Remixなどのフロントエンドは別のアプリケーションで、RESTまたはGraphQL経由でコンテンツを取得し、レンダリングします。ここで最も役立つ考え方は、選んだCMSがSEOに直接与える影響はほとんどなく、すべてを決めるのはフロントエンドのレンダリング判断であるということです。ヘッドレスSEOの議論は、常に「フロントエンドはこのコンテンツをどのようにレンダリングしているか」という問いから始めるべきです。 Evidence for this claim A headless CMS supplies content through APIs while a separate frontend controls how pages are rendered. Scope: Contentful as a representative headless CMS architecture. Confidence: high · Verified: Contentful: What is a headless CMS?
したがって、「ヘッドレスはSEOに悪い」という捉え方は適切ではありません。ヘッドレス自体は中立です。SSRまたはSSGを使い、メタデータを厳密に管理したヘッドレスサイトは、放置されたWordPressサイトより高い成果を出せます。一方、クライアントサイドレンダリングを初期設定のまま使い、メタデータ層を再実装しなかったサイトは、気づかないうちに崩れていきます。私のJavaScript SEOガイド でも述べているとおり、WebはプレーンHTMLだけの世界から移行しました。SEO担当者はその変化に抗うのではなく、受け入れて活用できます。
CMS、API、フロントエンドの担当範囲
「CMSはSEOにほぼ中立」という理解は正しいものの、担当範囲を明確にしなくてよいという意味ではありません。コンテンツモデルが保存するのは、構造化されたタイプとフィールドだけです。それだけでは、タイトル、canonical、schema、リンクが実際に出力される保証にはなりません。フロントエンドが役割を果たして初めて出力されます。 Evidence for this claim A headless CMS content model defines structured types and fields, but the consuming frontend owns URL routing and the rendered HTML that titles, canonicals, schema, and links depend on. Scope: Contentful content-model docs plus Next.js metadata docs as representative frontend evidence. Confidence: high · Verified: Contentful: Data model Next.js: Metadata and OG images 責任を明示的に分ければ、私が最もよく目にする2つの失敗を避けられます。1つは誰も担当せず、必要なものが黙って実装されないこと。もう1つは3つの層すべてが自分の担当だと考え、後述するcanonicalのようにロジックが分断されることです。
| レイヤー | 担当するもの | 担当しないもの |
|---|---|---|
| CMSコンテンツモデル | タイトル、ディスクリプション、スラッグ、OG画像、robotsの上書きなどを生データとして保持する構造化フィールド | フィールドをHTMLへどう出力するか、そもそも出力するかどうか |
| Delivery API(公開済みコンテンツ) | 公開済みで本番利用可能なコンテンツだけをライブサイトへ提供すること | プレビュー/未公開コンテンツ(それらには別のAPIを使う) |
| Preview/Management API | 独自のトークン/ホストで保護された未公開コンテンツと下書き | 本番フロントエンドが参照すべきもの |
| フロントエンド/ビルド/デプロイ | 最終的にレンダリングされるHTML:<head>タグ、canonical、サイトマップ、robots.txt、JSON-LD、内部リンク、ロケールルーティング | コンテンツの保存(APIを利用する側であり、モデルを定義する側ではない) |
呼び出すAPIの種類も区別する必要があります。Delivery、Management、Previewの各APIでは、公開状態と認可の意味が異なります。本番レンダリングでは公開済みコンテンツ用APIだけを使用し、Management APIやPreview APIのトークン/エンドポイントは決して使用しないでください。未公開コンテンツや書き込み権限が公開レスポンスに漏れるおそれがあります。 Evidence for this claim Delivery, management, and preview APIs have different publication and authorization semantics; production rendering must use the published-content API and must not expose management or preview tokens. Scope: Contentful API basics and Preview API docs as representative headless-API evidence. Confidence: high · Verified: Contentful: API basics Contentful: Content Preview API overview
GoogleがJavaScriptページを処理する流れ
GoogleはJavaScriptページを、クロール、レンダリング、インデックス登録の順に処理します。クライアントレンダリングに依存するページでは、最初のHTMLレスポンスに最終的なコンテンツが含まれません。一方、SSRとSSGはブラウザーが実行される前のレスポンスにコンテンツを含めます。 Evidence for this claim Google crawls, renders, and indexes JavaScript pages, while server-side or pre-rendered HTML exposes content in the initial response. Scope: Google Search JavaScript processing; indexing is not guaranteed. Confidence: high · Verified: Google: JavaScript SEO basics
大規模サイトでは、関連する2つの事実が重要です。Googleはブロックされたファイル内のJavaScriptをレンダリングできないため、必要な.jsと.cssリソースはクロール可能にしておく必要があります。また、JavaScriptのレンダリングには実際に大きなコストがかかります。Ahrefsでは1日に数十億ページをクロールしていますが、JavaScriptページのレンダリングはインフラの相当な部分を消費します。「Googlebotはレンダリングできる」と「Googlebotにレンダリングさせるべき」は同じではありません。
AIクローラーの実情
これは、ヘッドレスSEOの助言で見落とされがちな2026年の論点です。ChatGPT、Perplexityなどの背後で動く取得ボットを含め、ほとんどのAIクローラーはJavaScriptを実行しません。Vercelの調査は、いずれもクライアントサイドのコンテンツをレンダリングしないと端的に示しています。重要なページがJavaScript依存のSPAとして配信されている場合、AI検索からは実質的に見えません。Googleのレンダリングチームは、ほぼすべてのHTMLページをレンダリングすると述べていますが、それはGoogleの話です。AIでの可視性を得るうえで、SSR/SSGは「あればよい」ものではなく、参加条件です。
4つのレンダリング方式
SSG — Static Site Generation。 ビルド時にHTMLを生成し、CDNから静的ファイルとして配信します。最初のリクエストで完成済みのHTMLを返し、TTFBも非常に短いため、SEOでは最良の状態です。代償は更新性で、新規または変更されたコンテンツには再ビルドが必要になり、大規模サイトではビルドに時間がかかります(ISRはこの問題を一部解決します)。GatsbyとAstroはSSG中心で、Next.jsはルートごとに対応し、Hugoは代表的な例です。
SSR — Server-Side Rendering。 リクエストごとに、サーバーまたはエッジ関数でHTMLをレンダリングします。常に最新で完成済みのHTMLを最初のリクエストに返すため、SEOに非常に適しています。静的ファイルよりインフラコストが高く、TTFBがやや長くなる点が代償です。Next.js、Nuxt、SvelteKit、Remixはいずれも対応しています。
ISR — Incremental Static Regeneration。 再検証間隔を過ぎた後、バックグラウンドで静的ページを再生成します。通常はSEOに適していますが、次のセクションで説明する重要な落とし穴が1つあります。主にNext.jsの機能で、Nuxtにも類似機能があります。
CSR — Client-Side Rendering。 最小限のHTMLシェルを配信し、その後ブラウザーのJavaScriptがコンテンツを取得してDOMを構築します。SEOでは最も不利な選択肢です。Googlebotはページをレンダリング待ちのキューに入れる必要があり、処理時期を予測できません。AIクローラーや多くのボットには空のシェルしか見えません。CSRが適しているのは、ログインで保護され、そもそもインデックス登録すべきでない高度にインタラクティブなダッシュボードや認証専用ページです。見つけてほしいコンテンツには適していません。Next.js/Nuxtを使わない素のReactまたはVueのSPAは、初期状態ではここに該当します。
ISRで古いコンテンツが返る落とし穴
ISRの仕組みには、独立したセクションで扱う価値がある特有の問題があります。再検証期間が切れると、次のように動作します。
- 次に届いたリクエストがバックグラウンドでの再生成を開始する。
- そのリクエスト(Googlebotかもしれない)には、古いキャッシュページが返される。
- 新しいバージョンが配信されるのは、その次のリクエストからである。
クロール頻度の高いページでは、Googlebotが常に1回分の再検証サイクルだけ古いコンテンツを見る可能性があります。価格や在庫数など、本当に変動が激しいデータにはSSRのほうが安全です。ISRは、秒単位ではなく数時間または数日単位で変わるコンテンツに適した中間案です。
動的レンダリングは非推奨
数年前、私が2019年ごろに行った講演を含め、PuppeteerやRendertronのような仕組みでボットに事前レンダリング版を返す動的レンダリングは、妥当な回避策でした。しかし、Googleはその後この方針を変更しました。 公式文言は、“dynamic rendering was a workaround and not a long-term solution,” (翻訳) 「動的レンダリングは回避策であり、長期的な解決策ではなかった」、また*“creates additional complexities and resource requirements.”* (翻訳) 「複雑さとリソース要件をさらに増やす」です。Googleは現在、代わりにサーバーサイドレンダリング、静的レンダリング、またはハイドレーションを推奨しています。ここには注意点があります。動的レンダリングは自動的にクローキングとみなされるわけではなく、存在するだけでGoogleからペナルティを受けることもありません。ユーザーとクローラーにまったく異なるコンテンツを返した場合に初めてクローキングになります。「クローキングではない」と「公式に非推奨」は同時に成り立ちます。新規構築では採用しないでください。
メタデータ:プラグインが行っていた処理を再実装する
WordPressでは、YoastやRank Mathが各ページのタイトルとディスクリプションを自動生成していました。ヘッドレスにはプラグイン層がないため、次の作業を明示的に行います。
- CMSのコンテンツモデルにSEOフィールドを追加する — タイトル、ディスクリプション、robotsの上書き、canonicalの上書き、Open Graphフィールド。
- 各ページテンプレートの
<head>へフィールドを割り当てる — APIレスポンスから値を取得して出力します。 - フレームワーク標準のhead管理を使う — Next.jsの
generateMetadata(App Router)またはmetadataエクスポート、NuxtのuseSeoMeta、Gatsbyの<Seo>コンポーネント/react-helmet、Astroのレイアウトファイル内の<head>。
よくある不具合には、クライアントサイドで挿入したメタデータが最初ではなくレンダリング後に認識されること、共有レイアウトのcanonicalがページごとに更新されず、すべてがホームページをcanonicalにしてしまうこと、Next.js App RouterでmetadataBaseがなく相対canonical URLが壊れることがあります。信頼性の原則は単純です。HTMLに含まれるメタデータは、Googleが最初の取得時に認識できるため、JavaScriptで挿入するメタデータより確実です。HelmetやHeadのようなモジュールを使っても構いませんが、重要なタグはサーバーでレンダリングしたHTMLに含めてください。
コンテンツモデルには、単にフィールドを用意するだけでなく規則も必要です。そうしないと、前述のマッピング処理が気づかないうちに壊れます。
- フィールドごとに必須/任意を決める。 タイトルとcanonicalの上書きは必須(または自動導出)にし、空の
<title>で公開されないようにします。ディスクリプションとOGフィールドは、フロントエンドのフォールバックを用意したうえで任意にできます。 - フォールバックの順序を定義する。 SEOフィールドが空の場合に何を代入するか(ディスクリプションには本文抜粋、タイトルにはH1など)を事前に決め、テンプレートごとに場当たり的に処理せず、マッピング層で実装します。
- ロケールのフォールバックとフィールドのフォールバックを分ける。 翻訳がない場合、コンテンツAPIは既定ロケールの値を代入できます。本文では便利ですが、SEOフィールドが別ロケールのタイトル/ディスクリプションへ黙ってフォールバックするのは通常誤りであり、別途警告すべきです。
- マッピング時にエスケープする。 CMSのテキストフィールドではHTMLやリッチテキストを許可することがよくあります。
<title>、<meta>、JSON-LD文字列へ入れる前に除去またはエスケープしないと、マークアップが壊れ、悪い場合はスクリプトが挿入されます。 - ルート種別ごとに受け入れテストを行う。 公開前に、通常のエントリ、任意フィールドが空のエントリ、指定ロケールの翻訳がないエントリについて、レンダリングされた
<head>を確認します。正常系だけのテストでは捉えられない3つの異なるコードパスです。
ヘッドレス特有のリスク:canonicalの分断
WordPressではcanonicalは1か所にあります。ヘッドレスでは、CMSがスラッグを保存し、フレームワークがスラッグと環境設定から完全なURLを組み立て、コンポーネントが<link rel="canonical">タグを出力するという3つの層に分かれます。スラッグの変更、ルートパターンの変更、コンポーネントのリファクタリングなどでどれかの層がずれると、canonicalが存在しないURLを指すことがあります。以前のGoogleはJavaScriptで挿入したcanonicalを認識しませんでした。現在は一部で緩和されていますが、HTMLに含まれるcanonicalのほうがはるかに確実であり、競合するタグが複数あるとGoogleに選択を委ねることになります。
修正方法: canonicalのロジックはCMS内ではなくレンダリング層(フレームワーク)で一元管理し、単一のSITE_URL環境変数から絶対URLを生成します。信頼できる情報源は1つにし、常に絶対URLを使い、相対URLは使いません。
ロケールの担当範囲:APIフォールバックとフロントエンドルーティング
複数ロケールのヘッドレスサイトでも、canonicalと同様に担当範囲が混乱しがちです。コンテンツAPIのロケール選択とフォールバックは、リクエストされたロケールのコンテンツ、または設定済みの代替値を返すというフィールド値の置換を行えます。しかし、これはデータ置換機能であってSEO機能ではありません。 Evidence for this claim Content API locale selection and fallback can substitute field values, but the frontend still owns locale URLs, canonicals, hreflang, x-default, and language negotiation. Scope: Contentful localization docs plus Google rendering/canonical guidance. Confidence: high · Verified: Contentful: Localization Google: JavaScript SEO basics 検索に関わる次の要素は、引き続きフロントエンドが担当します。
- ロケール別URL。 ロケールをパス(
/es/page)、サブドメイン、別ドメインのどこに置くかはフロントエンドのルーティング判断です。APIはURLを生成しません。 - ロケールごとのcanonical。 各ロケール版は、すべて既定ロケールを指すのではなく、それぞれ自分自身をcanonicalにします。
hreflangとx-default。 フロントエンドが把握するロケールルートから代替言語リンク一式を生成し、該当しない言語向けのx-defaultも含めます。APIにはhreflangの概念がありません。- コンテンツネゴシエーションとステータスの挙動。 あるエントリに存在しないロケールがリクエストされた場合、既定ロケールへリダイレクトする、そのロケールのURLでフォールバックコンテンツを返す、実際の404を返す、のいずれかを意図的に決め、一貫して適用します。Googleにとって「APIが英語テキストを黙って代入した」と「このロケール版は存在しない」は異なる状況であり、必要なHTTPステータスコードも異なります。
実務上の落とし穴は、APIレベルのフォールバックによって、翻訳が欠けていてもCMSプレビューでは問題がないように見えることです。常に何らかのコンテンツが表示され、空のフィールドが見えないため、ロケールの欠落は編集上の警告より先にSEO問題として表面化しがちです。たとえば、誤った言語のタイトルが不適切なhreflangの下でインデックス登録されたり、ロケール間の重複コンテンツが発生したりします。
サイトマップとrobots.txt
Yoastがなければ、サイトマップも自動では作られません。プログラムで生成してください。Next.js App Routerでは、/sitemap.xmlを、ビルド時またはリクエスト時にCMSへ問い合わせるsitemap.tsファイルから生成できます。Nuxtにはサイトマップモジュール、Gatsbyにはgatsby-plugin-sitemap、Astroには@astrojs/sitemapがあります。公開頻度の高いサイトでは、ビルド時に生成した静的サイトマップが古くなる点が落とし穴です。コンテンツタイプ別に分割し、ISRで再生成するサイトマップを使います。
robots.txtも明示的に用意する必要があります。/public内の静的ファイル、または生成ルート(Next.jsのrobots.ts)として作成します。絶対に誤ってはいけない原則は、.jsや.cssをdisallowしないことです。ブロックするとレンダリングそのものができなくなります。
公開状態との同期を保つ
キャッシュと再検証は、パフォーマンスだけでなく編集内容の正確性に関わる問題です。時間、タグ、パスに基づく無効化は、設計どおりであっても古いコンテンツを配信することがあります。そのため、公開操作はCMSだけでなく、コピーをキャッシュしたすべての層へ届く必要があります。 Evidence for this claim Time-, tag-, and path-based cache invalidation can serve stale content by design, so publish, unpublish, rename, and locale changes need webhook-triggered purge and rollback handling, not a fixed timer. Scope: Next.js current cache/revalidation model. Confidence: high · Verified: Next.js: Revalidating 公開前に、公開、非公開化、名前/スラッグ変更、ロケール更新という4つのイベントで次の各項目がどう動くかを書き出し、テストしてください。
- 対象エントリのAPI/CDNキャッシュ。
- フレームワークのページキャッシュ(ISR/オンデマンド再検証、タグまたはパス単位)。
- フロントエンド手前のCDNエッジキャッシュ。
- サイトマップ — エントリの追加、削除、新URLでの再掲載。
- メタデータ — 古いcanonical/URLを完全に廃止し、新URLと並行して解決可能なまま残さない。
- ロールバック — 公開を取り消した場合、前方向だけでなく逆方向にもパージが動くことを確認する。
トリガーには固定タイマーではなく、CMSの公開/非公開イベントから送るWebhookを使い、フレームワークのタグまたはパス単位の再検証(revalidateTag、revalidatePath、または同等機能)を呼び出します。タイマー方式では、4つのイベントすべてが即時反映されず、次の周期まで待つことになります。
内部リンクと構造化データ
内部リンクは実際の<a href>タグでなければなりません。JavaScriptで遷移する<div onClick>や<span>はクロールできません。Googlebotがたどるのは本物のアンカーだけです。また、JavaScriptでレンダリングされるリンクはレンダリング段階まで発見されず、遅延が生じます。API駆動のコンテンツは、それだけではリンク構造を作りません。関連記事、パンくずリスト、本文内リンクはすべてコンポーネント層で実装する必要があります。
構造化データは、WordPressよりヘッドレスのほうが簡単になり得る珍しい領域です。JSON-LDをサーバーでレンダリングした<head>へ直接入れれば、クライアントバンドルの負荷はなく、コードでバージョン管理でき、プラグイン同士の競合もありません。コンテンツサイトで一般的なArticle/BlogPosting、BreadcrumbList、FAQPage、Organizationはいずれも利用できます。JavaScriptの挿入タイミングでテスト結果が変わる可能性があるため、レンダリングを変更した後はリッチリザルトテストで確認してください。
プレビュー環境とステージング環境
ヘッドレス構成では、プレビューURLやブランチデプロイURL(Vercel/Netlifyのプレビューデプロイ、CMSの下書きエンドポイント)が生成され、それらが公開アクセス可能なことも少なくありません。Googleにインデックス登録されると、別ホスト上にサイト全体の重複コピーがあるように見えます。対策は、ホストレベルでnoindex HTTPヘッダーを適用すること(CSRページが後から挿入するメタタグだけに頼らず、環境設定で行う)、署名付きトークンでプレビューを保護すること、ステージングが自己参照canonicalを出さないよう環境別canonicalを設定すること、短命なプレビューホストを使うことです。Search Consoleで予期しないドメインが現れていないか監視すると、早期警告になります。
防御の順序を正しくしてください。最初にnoindexを設定して終わりにしがちですが、noindexが機能するには、Googleがページをクロールしてタグを確認できる必要があります。これはインデックス登録に関する依頼であり、アクセス制御ではありません。ページが公開アクセス可能なら、執拗なクローラーや漏えいしたリンクへの対策にはなりません。 Evidence for this claim A noindex rule is not access control and requires Google to crawl the page to see it; private headless previews should be authenticated first, with noindex as a secondary indexing safeguard. Scope: Google noindex documentation plus Contentful/Sanity preview-token separation as representative platform evidence. Confidence: high · Verified: Google: Block Search indexing with noindex Sanity: Presenting and previewing content 本当の境界は、さらに上流に置く必要があります。
- まず認証する。 プレビュー環境は、何かを返す前に署名付きトークンまたはログインを要求すべきです。
noindexは、どうしてもアクセス可能にする必要があるページ向けの二次的な安全策であり、主要な制御ではありません。 - 環境ごとにトークンとホストを分ける。 プレビューと本番でAPIトークンやホスト名を共有してはいけません。未公開コンテンツを参照できるのはプレビュー用トークンだけであり、本番ビルドに混入させてはいけません。
- 正しいコンテンツ視点を問い合わせる。 本番コードは公開済みコンテンツだけを問い合わせ、下書き/プレビュー視点を使うのはプレビュー環境だけにします。逆にすると、認証と
noindexの両方があっても、本番から未公開エントリが漏れる可能性があります。
BingとIndexNow
Bingbotは現在、Googlebotと同じWebプラットフォーム技術であるMicrosoft Edge(Chromium)を使ってJavaScriptをレンダリングします。ただし、Googleほど一貫していません。Screaming Frogのテストでは、BingのJavaScriptインデックス登録は*“far from reliable,”* (翻訳) 「信頼できる状態にはほど遠い」とされ、結論も率直です。“if you care about SEO and sleeping at night, don’t rely on client-side rendering.” (翻訳) 「SEOと安心して眠ることを大切にするなら、クライアントサイドレンダリングに頼らないこと」。Bingからのトラフィックが重要なら、SSR/SSGはさらに重要です。
Bingはプッシュ型モデルも重視しています。ヘッドレスのコンテンツ更新はAPIを通るため、WordPressプラグインのようにBingへ通知しません。そこでIndexNowが特に役立ちます。CMSの公開WebhookにIndexNowのトリガーを接続し、変更URLを即時通知してください。Fabrice Canelが示すクロール効率の考え方も重要です。URLは少なく、整理されているほうがよいため、API駆動のファセットナビゲーションによってcanonicalのないパラメーターURLを何千件も生成しないようにします。
トラフィックを失わずにヘッドレスへ移行する
ヘッドレスSEOが実際に失敗しやすいのは移行時です。業界分析では、WordPressからヘッドレスへの移行で大幅なトラフィック減少と長期の回復が頻繁に報告されています。約50%の減少や約523日の回復といった数値は、正確な予測値ではなく、失敗した移行がどれほど深刻になり得るかを示す方向性のある警告として扱ってください。根本原因は予測できます。壊れた301(特に忘れられがちなカテゴリ、タグ、ページ分割されたアーカイブ)、引き継がれなかったメタデータ、気づかないうちにCSRになったレンダリング方式です。投稿だけでなくすべてのURLを棚卸しし、公開前に完全な301マップを作成し、新フロントエンドのメタデータとcanonicalを確認します。公開前後にScreaming Frogのクロールを比較し、GSCとBing Webmaster Toolsの両方へサイトマップを再送信し、IndexNowを導入してください。完全な一覧は移行チェックリストタブを参照してください。
関連資料はJavaScript SEOとレンダリングのトピックにあります。ヘッドレスSEOは、実質的にはこの2つを特定用途へ応用したものです。
AI要約
Advanced版の要点をまとめます。
- アーキテクチャがプロダクトを決める。 CMSバックエンドはSEOにほぼ中立で、すべてを決めるのはフロントエンドのレンダリング方式です。「ヘッドレスはSEOに悪い」は誤解です。
- 担当範囲: CMSコンテンツモデルは生の構造化フィールド、Delivery APIは本番向けの公開済みコンテンツ、Preview/Management APIは独自トークン/ホスト上の下書き、フロントエンド/ビルドは実際にレンダリングされる
<head>、canonical、サイトマップ、robots.txt、schema、ロケールルーティングを担当します。本番からPreview/Management APIやそのトークンを決して呼び出してはいけません。 - レンダリング方式: SSGとSSRは完成済みHTMLを配信する安全な選択肢です。CSRは最もリスクが高く、コンテンツは後のレンダリング段階まで存在しません。ISRは優れた中間案ですが、落とし穴があります。
- ISRの落とし穴: 再検証期間後の次のリクエスト(Googlebotかもしれない)にも古いページが返り、新しいページが配信されるのはその次です。変動の激しいデータにはSSRを使います。
- 動的レンダリングは非推奨: Googleは現在、SSR、静的レンダリング、ハイドレーションを推奨しています。自動的にクローキングになるわけではありませんが、新規構築では使いません。
- AIクローラーのレンダリングはプロバイダーごとに異なる: CSRページは、共通契約で保証されないクライアント実行に依存します。SSR/SSGが最も広いカバレッジを得られます。
- プラグインの機能を再実装する: コンテンツモデルのSEOフィールド →
<head>へのマッピング → サイトマップとrobots.txtの明示的な生成。.js/.cssは決してブロックしません。 HTMLのメタデータはJavaScript挿入より確実です。フォールバック順序を定義し、リッチテキストを<title>やJSON-LD文字列へ入れる前にエスケープします。 - canonicalは分断される: CMSのスラッグ → フレームワークのURL → コンポーネントのタグにまたがります。単一の
SITE_URLから絶対URLを作り、レンダリング層で設定します。 - ロケールも同様に分担する: APIのロケールフォールバックはコンテンツを代入しますが、ロケール別URL、ロケールごとのcanonical、
hreflang、x-default、翻訳欠落時の挙動はフロントエンドが担当します。 - リンクは本物の
<a href>にする:<div onClick>はクロールできません。 - プレビュー防御の順序: まず認証し、プレビュー/本番のトークンとホストを分離し、本番では公開済みコンテンツだけを問い合わせます。
noindexは二次的な安全策でありアクセス制御ではありません。Googleがタグを見るにはページをクロールする必要があります。 - 公開/非公開化/名前変更/ロケール変更ではWebhookによるパージが必要: APIキャッシュ、フレームワークキャッシュ、CDN、サイトマップ、メタデータを固定タイマーではなく即時に更新し、ロールバック経路も用意します。
- BingはEdgeでJavaScriptをレンダリングしますがGoogleほど安定しません。CMSの公開WebhookでIndexNowを呼び出します。Googleには約2 MBのリソース上限があります。
- 移行は壊れた恒久リダイレクト、失われたメタデータ、意図しないCSRで失敗します。公開前に全URLの棚卸しとリダイレクトマップを作成します。
公式ドキュメント
検索エンジンが公開している一次資料です。
- JavaScript SEOの基本を理解する — クロール → レンダリング → インデックス登録の流れ、JavaScriptでのcanonical、SPAのsoft 404s、History APIの指針。
- 動的レンダリング(非推奨の回避策) — Googleが非推奨にした理由と、代わりに使うSSR、静的レンダリング、ハイドレーション。
- 検索に関するJavaScriptの問題を修正する — レンダリング済みDOMの問題、ステートレスレンダリング、強いキャッシュに対するフィンガープリントの診断。
- コンテンツ駆動型Webアプリのレンダリング — コンテンツサイトにおけるSSR、SSG、CSRのトレードオフ。
- Webでのレンダリング(web.dev — Addy Osmani、Jason Miller) — SSR、CSR、ハイドレーションの標準的な定義と、完全な再ハイドレーションよりSSRまたは静的レンダリングを優先する推奨事項。
Bing/Microsoft
- 新しいevergreen Bingbot(Microsoft Edge) — Googlebotと同じWebプラットフォーム技術でJavaScriptをレンダリングするBingbot。
- IndexNow / indexnow.org — CMSの公開Webhookに接続するプッシュ型プロトコル。
出典からの引用
GoogleとBingの公式発言です。各リンクは、出典ページ内の引用箇所へ直接移動します。
Google — JavaScriptページの処理方法
- “All pages returning a 200 HTTP status code are queued for rendering, no matter whether JavaScript is present on the page.” (翻訳) 「ページにJavaScriptがあるかどうかにかかわらず、200 HTTPステータスコードを返すすべてのページはレンダリング待ちのキューに入ります」 — Google Search Centralドキュメント。 引用箇所へ移動
- “Google Search won’t render JavaScript from blocked files or on blocked pages.” (翻訳) 「Google検索は、ブロックされたファイル内またはブロックされたページ上のJavaScriptをレンダリングしません」 — Google Search Centralドキュメント。 引用箇所へ移動
- “Don’t use fragments to load different page content.” (翻訳) 「異なるページコンテンツの読み込みにフラグメントを使用しないでください」(代わりにHistory APIを使用) — Google Search Centralドキュメント。 引用箇所へ移動
Google — 動的レンダリングは非推奨
- “Dynamic rendering was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines.” (翻訳) 「動的レンダリングは、検索エンジンにおけるJavaScript生成コンテンツの問題に対する回避策であり、長期的な解決策ではありませんでした」 — Google Search Centralドキュメント。 引用箇所へ移動
- 代わりの推奨:“server-side rendering, static rendering, or hydration.” (翻訳) 「サーバーサイドレンダリング、静的レンダリング、またはハイドレーション」 — Google Search Centralドキュメント。 引用箇所へ移動
- “…creates additional complexities and resource requirements.” (翻訳) 「追加の複雑さとリソース要件を生じさせます」 — Google Search Centralドキュメント。 引用箇所へ移動
Google — SSR/静的レンダリングを優先する(web.dev)
- “We encourage developers to consider server-side rendering or static rendering over a full rehydration approach.” (翻訳) 「完全な再ハイドレーション方式より、サーバーサイドレンダリングまたは静的レンダリングを検討することを開発者に推奨します」 — Addy Osmani、Jason Miller(web.dev)。 引用箇所へ移動
2つのチェックリスト:ヘッドレスSEOの健全性と移行
ヘッドレスSEOの健全性チェック
- ページのコンテンツが、クライアントサイドJavaScriptの実行後だけでなく、最初のリクエストのHTML(SSRまたはSSG)に含まれている。
- 重要なページの主要コンテンツがCSRに依存していない(AIクローラーはJavaScriptを実行しない)。
- SEOフィールド(タイトル、ディスクリプション、robots、canonical、OG)がCMSコンテンツモデルにあり、
<head>へ割り当てられている。 - canonicalが単一の
SITE_URLから作る絶対URLで、レンダリング層にページごとに設定されている。共有のホームページcanonicalになっていない。 -
robots.txtが存在し、.jsや.cssをブロックしていない。 - サイトマップがプログラムで生成され、最新に保たれている(公開量の多いサイトではISR再生成/分割)。
- 内部リンクが実際の
<a href>タグであり、<div onClick>による遷移ではない。 - 構造化データ(JSON-LD)がサーバーでレンダリングした
<head>にあり、リッチリザルトテストに合格する。 - プレビュー/ステージングホストがホストレベルの
noindexヘッダーを返す。 - CMSの公開イベントでIndexNowが実行される(Bingなど向け)。
移行チェックリスト(従来型CMS → ヘッドレス)
- 投稿だけでなく、著者ページ、タグページ、ページ分割されたアーカイブ、パラメーターURLを含む完全なURL棚卸し。
- 変更されるすべてのURLについて、公開前に作成した301リダイレクトマップ。
- メタデータ(タイトル、ディスクリプション)を移行し、URLごとに確認した。
- 新フロントエンドのcanonicalタグを確認した。
- レンダリング方式が意図しないCSRではなく、SSR/SSGであることを確認した。
- Google Search ConsoleとBing Webmaster Toolsへサイトマップを再送信した。
- 公開前後でクロール比較(Screaming Frog)を実行した。
- 新しいドメイン/プロトコル用のSearch Consoleプロパティを設定した。
- IndexNowを実装した。
判断に使う考え方
1. アーキテクチャがプロダクトを決める。 CMSバックエンドはSEOにほぼ中立です。プロダクトを決めるのはフロントエンドのレンダリング方式です。ヘッドレスサイトの問題を調べる前に、まず「フロントエンドはこのコンテンツをどのようにレンダリングしているか」と問いましょう。ほぼすべてのヘッドレスSEO問題は、この問いに行き着きます。
2. レンダリング方式の判断基準。 コンテンツの変更頻度とインタラクティブ性で選びます。
- ほぼ静的なコンテンツ(ブログ、ドキュメント、マーケティング)→ SSG(再ビルドまたはタイマー式ISR)。
- 頻繁に変わり、常に最新でなければならないコンテンツ(価格、在庫)→ SSR。
- 数時間/数日単位で変わり、静的ファイルの速度が必要 → ISR(再検証後の最初のリクエストで古い内容を返す点に注意)。
- 高度にインタラクティブで、ログインの背後にあり、インデックス登録しない → CSRでもよい。
- 検索順位やAIでの引用を狙う公開コンテンツ → CSRは使わない。
3. 「プラグインが行っていた処理を再実装する」。
Yoast/Rank Mathが自動処理していたすべての機能が、明示的なビルド工程になります。コンテンツモデルのメタデータフィールド → <head>へのマッピング → サイトマップ → robots.txt → canonical → 構造化データ。「何かがない」場合、多くはプラグインの機能が再実装されていません。
4. URLの信頼できる情報源を1つにする。
canonical、サイトマップのエントリ、内部リンクはすべて、3つの層で手作業により組み立てたスラッグではなく、単一のSITE_URLとフレームワークのルーティングから導出します。情報源を1つにすれば、canonicalの分断を防げます。
5. HTMLを先に、JavaScriptを後に。 コンテンツ、メタデータ、canonical、内部リンク、構造化データなど、クロールとインデックス登録に重要なものはサーバーでレンダリングしたHTMLに含めます。JavaScriptで挿入するSEOシグナルは基本方針ではなくフォールバックとして扱います。Googleには遅れて認識され、ほとんどのAIクローラーにはまったく認識されないためです。
ヘッドレスSEO — チートシート
レンダリング方式の早見表
| 方式 | HTMLを生成する場所 | SEO | 最適な用途 | 注意点 |
|---|---|---|---|---|
| SSG | ビルド時 → 静的ファイル | ✅ 最適 | ほぼ静的なコンテンツ | 再ビルドまで古いまま。大規模ではビルドが遅い |
| SSR | リクエストごとにサーバー | ✅ 最適 | 常に最新のコンテンツ | インフラコストが高く、TTFBがやや長い |
| ISR | 静的 + 時間指定のバックグラウンド再生成 | ✅ 良好 | 時間/日単位のコンテンツ | 再検証後の最初のリクエストには古いページを返す |
| CSR | ブラウザー内 | ⚠️ リスクあり | ログイン後のダッシュボード | AIクローラーには空のシェル。レンダリング段階まで遅延 |
フレームワーク別のメタデータ管理
| フレームワーク | head管理 | サイトマップ |
|---|---|---|
| Next.js(App Router) | generateMetadata/metadataエクスポート | sitemap.ts → /sitemap.xml |
| Nuxt | useSeoMeta composable | サイトマップモジュール |
| Gatsby | <Seo>コンポーネント/react-helmet | gatsby-plugin-sitemap |
| Astro | <head>(レイアウト.astro内) | @astrojs/sitemap |
簡潔なルール
- robots.txtで
.js/.cssを絶対にdisallowしない。 - canonicalは単一の
SITE_URLから作る絶対URLとし、レンダリング層で設定する。 - Next.js App Routerでは
metadataBaseを設定する。ないと相対canonicalが壊れる。 - 内部リンクは実際の
<a href>にする。<div onClick>はクローラーから見えない。 - プレビュー/ステージングでは、後からJavaScriptで挿入するメタタグではなく、ホストレベルの
noindexヘッダーを使う。 - Googleのリソース上限は約2 MBで、それを超える部分は切り捨てられる。
- 動的レンダリングは非推奨。SSR/静的レンダリング/ハイドレーションを使う。
- ほとんどのAIクローラーはJavaScriptを実行しないため、CSRコンテンツは見えない。
- BingはEdgeでJavaScriptをレンダリングするが、信頼性はGoogleより低い。公開イベントにIndexNowを接続する。
サーバーが配信するレスポンスを監査する
代表的なフロントエンドルートをurls.txtへ書き出します。サーバーでレンダリングされていないメタデータがハイドレーションで隠れないよう、ここでは意図的にブラウザーではなく生のレスポンスを使います。
while IFS= read -r url; do
html=$(mktemp)
status=$(curl -sS -o "$html" -w '%{http_code}' "$url")
title_count=$(grep -Eio '<title>[^<]*</title>' "$html" | wc -l | tr -d ' ')
canonical_count=$(grep -Eio '<link[^>]+rel=["'"']canonical["'"'][^>]*>' "$html" | wc -l | tr -d ' ')
jsonld_count=$(grep -Eio '<script[^>]+type=["'"']application/ld\+json["'"']' "$html" | wc -l | tr -d ' ')
printf '%s\t%s\ttitles=%s\tcanonicals=%s\tjsonld=%s\n' "$status" "$url" "$title_count" "$canonical_count" "$jsonld_count"
rm -f "$html"
done < urls.txt意図的にストリーミングする、または後からコンテンツを読み込むルートについては、レンダリング後の比較を別途実行してください。CMSのプレビュートークンをURL一覧へ決して入れないでください。
ヘッドレスSEOの診断ツール
- URL Inspection(Google Search Console) — 単一URLがどのようにクロールされ、レンダリングされたかを確認します。レンダリング済みHTML/スクリーンショットから、コンテンツが実際に含まれたかを判断でき、CSRの欠落を見つけるのに不可欠です。
- リッチリザルトテスト — レンダリング変更後に、JSON-LDがレンダリング結果に含まれているかを確認します。JavaScriptの挿入タイミングによって検出結果が変わることがあります。
- Screaming Frog SEO Spider — JavaScriptレンダリングのオン/オフでクロールし、生のHTMLとレンダリング済みHTMLを比較します。移行前後のクロール比較にも使えます。
- Ahrefs Site Audit — フロントエンド全体のリダイレクトチェーン、壊れたcanonical、欠落したメタデータ、インデックス可能性の問題を検出します。
- Bing Webmaster Tools — Bingから見たレンダリング/インデックス登録と、IndexNow送信の状況を確認します。
ヘッドレス構築で繰り返し見かける誤り
マーケティングサイトをクライアントレンダリングのSPAとして公開する。 SSR/SSG層のない素のReactまたはVueフロントエンドは、最も一般的なヘッドレスSEOの失敗です。問題点: Googlebotがコンテンツを認識するには、ページを2回目のレンダリング段階へ入れる必要があります。一方、AIプロバイダーが公開するレンダリング契約は異なり、不完全な場合もあります。HTMLだけを取得するボットには空のシェルしか見えません。代わりに: Next.js、Nuxt、Astro、Gatsbyなど、完成済みHTMLを初期状態で配信するフレームワークを選び、見つけてほしいページにはSSRまたはSSGを使います。
CMSのslugフィールドをcanonical URLとして扱う。 開発者はCMSが返す値から<link rel="canonical">を直接生成しがちです。問題点: canonicalがCMSのスラッグ、フレームワークのルーティング、コンポーネントのロジックに分断され、スラッグ名の変更やルートのリファクタリングで黙って壊れます。代わりに: CMS出力から直接作らず、単一のSITE_URL環境変数を使ってレンダリング層でcanonicalを生成します。
プレビュー/ステージングのデプロイを公開クロール可能なままにする。 Vercel/NetlifyのプレビューURLとCMSの下書きエンドポイントは、初期状態でアクセス可能なことがあります。問題点: Googleが発見すると、別ホスト上のサイト全体の重複コピーをインデックス登録する可能性があります。JavaScriptで遅れて挿入するnoindexメタタグだけでは防げないこともあります。代わりに: ホストレベルでnoindex HTTPヘッダーを適用し、署名付きトークンでプレビューを保護します。
ISRを設定すれば常に最新だと思い込む。 チームは「十分に新しい」という理由でISRを選び、その仕組みを深く考えなくなりがちです。問題点: 再検証期間後に再生成を開始するリクエスト(Googlebotかもしれない)にも古いキャッシュページが返り、更新版を見るのはその次のリクエストだけです。代わりに: 数時間/数日単位で変わるコンテンツにはISRを使い、価格や在庫数など本当に変動の激しいデータにはSSRを使います。
ナビゲーションや関連記事リンクをクリック可能な<div>で作る。 コンポーネントライブラリを使うと、どの要素にもonClickのナビゲーション処理を簡単に付けられます。問題点: 検索エンジンがたどるのは実際の<a href>アンカーだけです。<div onClick>は訪問者にリンクのように見えても、クローラーからは見えません。代わりに: APIから取得する関連記事やパンくずリンクを含め、すべての内部リンクを実際のアンカータグとして出力します。
「クロールバジェット節約」のためrobots.txtで.jsや.cssをdisallowする。 古いrobots.txtを引き継いだヘッドレス構築では、予想以上によく見かけます。問題点: JavaScriptまたはCSSがブロックされたページをGoogleはレンダリングできません。クロールバジェットを節約するのではなく、レンダリング全体を壊します。代わりに: .jsと.cssはクロール可能にします。ブロックする正当な理由はありません。
症状 → 原因 → 修正
URL Inspectionでは取得できているが、レンダリング済みHTMLにコンテンツがない
原因: ページがクライアントサイドでレンダリングされ、ブラウザーでJavaScriptが実行された後にだけコンテンツが存在します。GoogleのURL Inspectionはレンダリング後のDOMを表示するため、そこにも主要コンテンツがないなら、レンダリング段階で生成されていない(またはまだ実行されていない)ということです。修正: 生のHTMLとレンダリング済みHTMLを比較するPatrickのRender Gapツールでレンダリング方式を確認します。実際に差がある場合は、クライアントサイド取得に頼らず、そのルートをSSRまたはSSGへ移します。
Search ConsoleでGoogleが報告するcanonicalがコード内のものと違う
原因: canonicalの分断です。CMSのスラッグ、フレームワークのURL組み立て、タグを出力するコンポーネントが同期しなくなっているか、共有レイアウトがすべてのページに同じcanonicalを出しています。修正: PatrickのCanonical Checkerでライブタグを確認し、canonicalの生成をレンダリング層へ移して、3つの別々な処理ではなく単一のSITE_URL変数から作ります。
ヘッドレス移行の直後にトラフィックが急減した
原因: ほとんどの場合、壊れた301です。特に、誰も移行マップへ入れなかったカテゴリ、タグ、ページ分割されたアーカイブが該当します。または、旧CMSからメタデータが引き継がれていません。修正: すべての旧URLをPatrickのRedirect Checkerへ通し、チェーンや404ではなく、正しい宛先へ1回の301で解決されることを確認します。その後、URLごとにタイトルとディスクリプションが移行されたか確認します。
プレビュー/ステージングURLがSearch Consoleやsite:検索に現れる
原因: プレビュー/ステージングホストがホストレベルでインデックス登録を防止されていません。クライアントサイドで挿入するnoindexメタタグは、Googleが認識するには遅すぎる場合があります。修正: ページマークアップだけでなく環境設定自体でnoindex HTTPヘッダーを適用し、署名付きトークンでプレビューホストを保護して、そもそも公開クロールできないようにします。
ソースコードに構造化データがあるのに、リッチリザルトテストで検出されない
原因: JSON-LDが最初のHTMLレスポンス後にクライアントサイドで挿入され、テストまたはGooglebotの最初の処理が確認するタイミングと合っていません。修正: JSON-LDをサーバーでレンダリングした<head>へ移し、ブラウザーでレンダリングされたDOMだけでなく生のレスポンスに対して、PatrickのSchema ValidatorまたはRich Result Eligibility Checkerで再確認します。
数か月前に削除または名前変更したURLがサイトマップに残っている
原因: サイト全体の再ビルド時にしか更新されない、ビルド時生成の静的サイトマップです。公開量の多いサイトでは、数日から数週間遅れることがあります。修正: コンテンツと同じ頻度で再生成するサイトマップ(ISR再生成またはコンテンツタイプ別の分割)へ切り替え、PatrickのSitemap Validatorで現在の出力を確認します。
このページにはどのレンダリング方式を使うべきか
レンダリング方式は、ヘッドレスページのSEOに関するほぼすべてを決める判断です。サイト全体で一度決めるのではなく、ルートごとに検討してください。マーケティングサイトと認証済みダッシュボードのルートでは、異なる結論になってよく、実際にそうすべきです。
Which rendering mode should this page use?
ヘッドレス移行後にトラフィックが減少した場合の手順
これは私が最もよく目にする状況で、根本原因も予測できます。順番に確認してください。各手順で問題が解決するか、その原因を除外して次へ進めます。
- 最初にSearch Consoleのクロール統計とカバレッジレポートを確認する。 公開直後に404が急増した、またはインデックス登録済みページが減った場合は手順2へ進みます。インデックス登録が安定しているのに順位/トラフィックが減った場合は手順5へ進みます。
- 壊れたリダイレクトを確認する。 投稿だけでなく、著者ページ、タグページ、ページ分割されたアーカイブを含む移行前の全URL一覧をPatrickのRedirect Checkerへ通します。404、リダイレクトチェーン、誤った宛先へ解決されるものがあれば、ほかの作業より先に301マップを作成または修正します。
- リダイレクトが正常なら、メタデータ移行を確認する。 移行前にトラフィックの多かったURLのタイトルとディスクリプションを抽出し、現在のライブページと比較します。旧CMSからメタデータが引き継がれなかったことは、移行後に減少する原因として2番目に多いものです。
- メタデータに問題がなければ、レンダリング方式を確認する。 新フロントエンドが黙ってCSRを初期値にしていないか確認します。PatrickのRender Gapツールでページのサンプルについて生のHTMLとレンダリング済みHTMLを比較します。SSR/SSGがCSRへ落ちるフレームワーク設定の誤りは、誰にも気づかれずに公開されやすい問題です。
- 以上がすべて正常なら、canonicalが分断されていないか確認する。 Canonical Checkerで抽出確認します。共有レイアウトのcanonicalや、移行中に変更されたスラッグによって、順位が誤ったURLへ集約されることがあります。
- Google Search ConsoleとBing Webmaster Toolsの両方へサイトマップを再送信する。 CMSの公開WebhookにIndexNowが接続され、新規/変更URLが再クロールを待たず継続的に通知されることも確認します。
- 手順2〜6を終えてもトラフィックが回復しない場合、 探し続ける不具合ではなく、長期の回復として扱います。技術的な問題をすべて修正しても、Googleが新しいサイト構造を再クロールし再評価する必要があるため、ヘッドレス移行が完全に回復するまでには実際に時間がかかります。
ヘッドレスSEO作業用のプロンプト
使用中のAIアシスタントへ貼り付け、角括弧内の入力を置き換えて使います。一般的な「SEOを監査して」というプロンプトではなく、この記事で扱う具体的な作業に限定しています。
1. ページコンポーネントからCSR専用コンテンツを見つける
ページ/テンプレートのコンポーネント(Next.jsのpage.tsxやNuxtの.vueファイルなど)を貼り付け、次のように依頼します。
Here is a page component from my headless CMS frontend. Identify any content
that is fetched or rendered only on the client (inside useEffect, onMounted,
or similar client-only hooks) rather than during server rendering or build.
For each one, tell me whether it would be present in the initial HTML
response or only appear after JavaScript runs in the browser.
[paste component code]サーバーレンダリングされたコンテンツとクライアント専用コンテンツを具体的なブロックごとに分類した一覧が得られます。AIクローラーやGoogleの最初の取得から見えないものを正確に把握できます。
2. canonical URL実装の分断リスクを確認する
canonicalタグを生成するコード(CMSフィールド、URL組み立てロジック、<link rel="canonical">を出力するコンポーネント)を貼り付け、次のように依頼します。
This is how my headless site builds its canonical URL across three layers:
the CMS content model, the framework's URL assembly, and the rendering
component. Identify any point where these could drift out of sync (a slug
change, a route change, a hardcoded fallback) and suggest how to consolidate
this into a single source of truth built from one SITE_URL variable.
[paste canonical-related code from CMS field, framework logic, and component]一般論ではなく、実際のコードに紐づいた具体的な分断リスクが得られます。
3. CMSコンテンツモデルへ追加するSEOフィールド案を作る
コンテンツタイプを説明し、次のように依頼します。
I'm setting up SEO fields in a headless CMS content model for [content type,
e.g. "blog post" / "product page"]. List the fields I should add (title,
description, robots override, canonical override, Open Graph fields, etc.),
a sensible field type for each, and which ones should have sensible
auto-generated defaults vs. requiring manual entry.
[describe your content type and any existing fields]一般的なチェックリストではなく、説明したコンテンツタイプに合わせてCMS設定担当者へ渡せるフィールド別の一覧が得られます。
4. 移行クロールで生のHTMLとレンダリング済みHTMLを比較する
2つのクロール結果(たとえばScreaming FrogでJavaScriptレンダリングのオフ/オンを切り替えた、生のHTMLとレンダリング済みHTMLのクロール)を貼り付け、次のように依頼します。
Here are two crawl exports of the same URL set from my headless site — one
crawled with JavaScript rendering off (raw HTML) and one with it on
(rendered HTML). Compare them and flag any URLs where the title, meta
description, canonical, or main content differs meaningfully between the two,
since that gap indicates content is only appearing after client-side
rendering.
[paste or summarize the two exports]生のHTMLとレンダリング済みHTMLが異なるURLの一覧が得られます。最初に修正すべきCSR依存ページです。
読む価値のある資料
私の関連記事
- JavaScript SEO Issues & Best Practices — このテーマのレンダリング面に関する私の主要資料で、ヘッドレスにも直接関係します。レンダリング方式、メタデータモジュール(Meta tags、Helmet、Head)、JavaScriptによるcanonical、サイトマップ、robots.txtの
Allow: .js / Allow: .cssルールを扱います。 - The Beginner’s Guide to Technical SEO — レンダリングとクロールが、より大きな枠組みのどこに位置するかを説明します。
私の講演
- JavaScript SEO — Ungagged 2019 (SlideShare)— ヘッドレス/分離型CMSがフロントエンドとバックエンドを分ける仕組み、Googlebotのステートレスなレンダリング挙動を解説した講演です。(継続的な注意事項:この資料内の動的レンダリングに関する推奨は現在では古く、Googleは非推奨にしています。)
ほかの執筆者による資料
- Webでのレンダリング (web.dev)— Addy OsmaniとJason Millerによるレンダリング方式の決定版。
- BingのJavaScriptレンダリング調査 (Screaming Frog)— BingがJavaScriptをどの程度一貫してインデックス登録するかについての実地検証。
- クライアントサイドとサーバーサイドのレンダリング (Search Engine Journal)— GoogleがすべてのHTMLをレンダリングする理由をMartin Splittが説明します。
- 2026年のJavaScriptなしフォールバック:重要性は低下したが、なお必要 (Search Engine Land、James Allen)— AIクローラーがJavaScriptを実行しないことと、Googleの2MBリソース上限を扱います。主要AIクローラーはいずれもクライアントサイドコンテンツをレンダリングしないというVercelの調査を参照しています。
- 検索順位に影響するアーキテクチャ判断 (Focus Reactive)— ヘッドレスの具体的なアーキテクチャ判断がSEO結果へどう影響するかを扱う、独立系の中でも厳密な記事です。
- ヘッドレスCMS入門ガイド (Oncrawl、Dan Taylor)— 分離型アーキテクチャとクロールへの影響を、テクニカルSEOの視点から説明します。
- ヘッドレスコマースのSEO要点 (Women in Tech SEO、Safia Marmon)— ヘッドレスEコマースSEOの実装ガイドで、メタデータ、canonical、サイトマップのパターンを扱います。
- Next.jsのメタデータとOG画像 (Next.jsドキュメント)— Advancedタブで扱った
generateMetadata、metadataBase、App Routerのhead管理パターンの公式資料。 - r/TechSEO — レンダリング/インデックス登録のデバッグを扱うコミュニティ。
変更履歴
2026年8月21日に更新。
編集概要と記録された変更の詳細。変更の詳細
-
変更の詳細な注記は現在英語でのみ提供されています。
完全な比較は利用できません — この改訂の以前のスナップショットがアーカイブされていません。
2026年8月3日に更新。
編集概要と記録された変更の詳細。変更の詳細
-
変更の詳細な注記は現在英語でのみ提供されています。
完全な比較は利用できません — この改訂の以前のスナップショットがアーカイブされていません。
2026年7月18日に更新。
編集概要と記録された変更の詳細。変更の詳細
-
変更の詳細な注記は現在英語でのみ提供されています。
-
変更の詳細な注記は現在英語でのみ提供されています。
-
変更の詳細な注記は現在英語でのみ提供されています。
-
変更の詳細な注記は現在英語でのみ提供されています。
-
変更の詳細な注記は現在英語でのみ提供されています。
完全な比較は利用できません — この改訂の以前のスナップショットがアーカイブされていません。