NuxtのSEO

Nuxtはデフォルトでサーバーサイドレンダリングを提供しますが、これはルートごとの設定であり、保証ではありません。クローラーに完全なHTMLを提供するのは、その設定を維持するルートのみです。レンダリングモード、useSeoMeta()、@nuxtjs/seoツールキット、ハイドレーションとNitroの注意点、Core Web Vitals、そして静かにコストをかけるミスについて解説します。

初回公開:2026年6月26日 · 最終更新:2026年8月13日 · Advanced
言語
このページには証拠シグナルが1件あります

Nuxtはデフォルトでページをサーバーレンダリングするため、そのデフォルトを維持するルートは、プレーンなVue SPAが提供する空のシェルではなく、クローラーに完全なHTMLドキュメントを提供します。ただし、これはルートごとの設定であり、routeRulesやグローバルなssr:falseによって任意のルートをCSRに切り替えることができるため、フレームワーク名から推測するのではなく、実際のルートを確認してください。基本的な決定はルートごとのレンダリングモード(SSR(デフォルト)、nuxt generateによるSSG、またはハイブリッドルートルール)です。メタタグ、スキーマ、サイトマップはすべてその後に続くからです。メタにはuseSeoMeta()を使用し、Harlan Wiltonの@nuxtjs/seoバンドルはrobots/sitemap/OG/schema/canonical用のオプションのサードパーティツールキット(Nuxtコアではない)として扱い、動的レンダリングには決して手を出さず(Googleは非推奨)、ハイドレーション/ペイロードとNitroのデプロイメントプリセット/キャッシュ動作をサーバーHTMLとは独立して検証し、AIクローラーのレンダリング契約はプロバイダーによって異なることを覚えておいてください。SSR/SSGはコンテンツを生のHTMLに配置し、カバレッジを最大化します。

TL;DR — Nuxtのデフォルトはサーバーサイドレンダリングなので、そのデフォルトを維持するルートは、素のVue SPAが配信する空のシェルではなく完全なDOMを取得します。ただし、これはルートごとの結果です。ssr: falserouteRulesの上書きにより、任意のルートをCSRやハイブリッドに変更できるため、プロジェクト名ではなく実際のルートをテストしてください。レンダリング戦略は基盤となる決定です。SSR(デフォルト)、SSG(nuxt generate)、またはハイブリッドrouteRulesのいずれかで、メタ、スキーマ、サイトマップはすべてその後に続くからです。メタタグにはuseSeoMeta()を使用し(それ以外のheadにはuseHead()、リアクティビティが不要な場合はサーバー専用バリアント)、Harlan Wiltonの@nuxtjs/seoバンドルはrobots/sitemap/OG/schema/canonical用のオプションのサードパーティツールキットとして扱ってください。Nuxtコアの一部ではなく、確認するまでその出力が正しいという証明にもなりません。動的レンダリングは使用しないでください(Googleは非推奨にしました)。AIクローラーのレンダリングはプロバイダーによって異なります。SSR/SSGは生のHTMLカバレッジを最大化します。初期HTMLの他に、ハイドレーション/ペイロード、Nitroデプロイメントプリセットとキャッシュ、直接のHTTPステータスを個別に検証してください。サーバーHTMLだけではそれらのいずれも証明できません。通常のJS-SEOルールは引き続き適用されます。実際の<a href>リンク、JS/CSSのブロック禁止、レンダリング済みHTMLと生HTMLの確認などです。

NuxtはSPA問題に対するVueの答え

Vue単体では、シングルページアプリケーション(HTMLシェルとブラウザでDOMを構築するJavaScript)を配信します。NuxtはVueの上に構築されたメタフレームワークで(Nuxt 3ではNitroサーバーエンジン上で動作し、Nuxt 4は2025年に続きます)、SEOの観点から見た存在理由は、デフォルトでサーバー上でレンダリングすることです。すべてのページが完全に形成されたHTMLドキュメントとして届くため、GooglebotがJavaScriptを実行せずに読み取るのに最適です。素のVue SEOは独自のトピックであり、独自の失敗モードがあります。ここでは、SPA問題と戦わなくて済むように、あなたがNuxtを選んだことを前提としています。

これはJavaScript全般について私が述べているのと同じ点です。“any kind of SSR, static rendering, and prerendering setup is going to be fine for search engines. Gatsby, Next, Nuxt, etc., are all great.” (翻訳) 「あらゆる種類のSSR、静的レンダリング、プリレンダリングの設定は検索エンジンにとって問題ありません。Gatsby、Next、Nuxtなどはすべて素晴らしいです。」(引用元: JavaScript SEO)Nuxtのデフォルトは正しい方向を向いています。NuxtのSEO問題のほとんどは、人々がこれらのデフォルトをオフにしたり、その上に間違いを重ねたりすることです。

レンダリング戦略が基盤 — プロジェクト単位ではなくルート単位で決定

メタタグ、スキーマ、サイトマップの前に、すべてを決定する質問は、この特定のルートに対してHTMLがどのように生成されるかです。Nuxtはユニバーサル(サーバー)レンダリングをアプリ全体のデフォルトとして文書化していますが、そのデフォルトはルートレベルの保証ではありません。グローバルなssr: falseはアプリ全体をクライアントレンダリングに切り替え、routeRulesは任意のURLパターンに異なるモードを割り当てることができます。「これはNuxtアプリだ」というだけでは、特定のページがどのようにレンダリングされるかはわかりません。ルートを確認する必要があります。Nuxtには5つの戦略があります。

モード設定方法SEOへの影響最適な用途
ユニバーサル / SSRデフォルト(ssr: true優れている — 毎リクエスト完全なHTML動的でパーソナライズされたコンテンツ
静的 / SSGnuxt generate優れている — デプロイ時にHTMLを構築ブログ、ドキュメント、マーケティング
ハイブリッドルートごとにrouteRules優れている — ルートごとに混在大規模な混合コンテンツサイト
SPA / CSRssr: falseインデックスされるコンテンツには不向きダッシュボード、管理パネル
エッジサイドデプロイメントターゲット優れている — 低TTFBグローバルパフォーマンス

公式のNuxtドキュメントは、クライアントサイドレンダリングがコンテンツにとって間違った選択である理由を率直に述べています:「クライアントサイドレンダリングを介して配信されるコンテンツのインデックス作成と更新にはより多くの時間がかかる」 一方、サーバー(ユニバーサル)レンダリングでは 「ウェブクローラーはページのコンテンツを直接インデックスできる。」 Evidence for this claim Nuxt documents that universal rendering delivers HTML content immediately and allows crawlers to index it directly. Scope: Nuxt rendering; no indexing guarantee. Confidence: high · Verified: Nuxt: Rendering modes (Nuxtレンダリングドキュメント。) CSR (ssr: false) は、バックオフィス、ダッシュボード、ゲーム向けに位置付けられています — インデックスさせたいものには向いていません。

ハイブリッドレンダリングは大規模サイトにとっての強力な手段です。 nuxt.config.ts のルートルールを使用すると、URLパターンごとにレンダリングモードとキャッシュモードを設定できます:

routeRules: {
  '/blog/**':     { prerender: true },        // SSG for the blog
  '/product/**':  { swr: 3600 },              // ISR-style: regenerate hourly
  '/admin/**':    { ssr: false },             // SPA for the admin area
  '/checkout/**': { ssr: true },              // always-fresh SSR
}

swr(stale-while-revalidate)と isr(インクリメンタル静的再生成)は、ページを静的に生成してからバックグラウンドで更新します — ページ数が多いeコマースやニュースサイトで、変更のたびに完全な再ビルドが現実的でない場合に最適です。Nuxt Islands (<NuxtIsland>) は、クライアントサイドのJavaScriptを配信せずにコンポーネントをレンダリングし、ハイドレーションコストを削減してINP — Nuxtアプリで最も問題になることが多いCore Web Vital — を改善します。

実際に配信したものを検証する方法: View Sourceはサーバーが送信した生のHTMLを表示します。コンテンツがそこにあれば、サーバーレンダリングされています。DevToolsのElementsパネルはレンダリングされたDOMを表示します。そしてGSCのURL Inspectionツールは、Googleが実際に取得してレンダリングしたものを表示します — これが真実の情報源です。「ブラウザで問題なく見える」を信頼しないでください。

GooglebotがNuxtアプリを処理する方法

GoogleはあらゆるJavaScriptアプリを3つのフェーズ — クロール、レンダリング、インデックス — で処理します。そして問題はタイミングです:レンダリングはキューで行われ、即座には実行されません。私のJavaScript SEOガイドで述べたように、レンダラーは忍耐強いです — 「レンダラーには固定のタイムアウトはありません… 本当に忍耐強く、心配する必要はありません。」 しかし、忍耐強いことは 新しい コンテンツにとって速いことと同じではありません。クライアントレンダリングされたページを配信する場合、そのレンダリングウェーブが実行されるまで、あなたのコンテンツはGoogleにとって存在しません。SSRとSSGは、最初のフェッチでHTMLが完全に揃っているため、そのギャップを埋めます。

大規模になると、さらに2つのことが重要になります。JavaScriptのレンダリングはコストがかかります — 私の2019年の*JavaScript SEOトーク(Ungagged)から、Googleがレンダリングしなければならない場合、クロールコストは約20倍に増加します(方向性は示しますが、桁は今も変わりません)。そしてGoogleは、生のHTMLとレンダリングされたHTMLの両方で最も制限の厳しいディレクティブを採用します — そのため、JavaScriptによって注入された noindex は生のHTMLの index に勝ち、その逆も同様です。JavaScriptを介して注入されたcanonicalは、生のHTMLにすでにcanonicalがない場合にのみ尊重されます。robotsとcanonicalのシグナルをサーバーレンダリングされたHTMLに保持してください。SSRがオンの場合、Nuxtが自動的に行います。

AIクローラーの現実

これが2026年の難点です。AIクローラー — GPTBot、ClaudeBot、PerplexityBot、その他 — は一般的にJavaScriptをまったく実行しません。生のHTMLのみをインデックスし、それ以外は何もしません。したがって、クライアントレンダリングされたNuxtページは、AIアンサーエンジンにとって事実上見えません。ここではSSRまたはSSGはGoogleにとって単に良いだけではなく、アンサーエンジン最適化のための参入条件でもあります。コンテンツをChatGPT、Perplexity、またはClaudeに引用させたい場合は、最初のフェッチでHTMLに含まれている必要があります。

初期HTMLを超えて:ペイロード、ハイドレーション、ステータスコード

コンテンツを含むサーバーHTMLを取得することは必要ですが、十分ではありません — 最初のレスポンスの後でも、いくつかのことがうまくいかない可能性があります。「View Sourceを確認した」ではそれらをカバーできません:

  • ペイロードとハイドレーション。 ユニバーサルレンダリングは、HTML 、クライアントがハイドレーション(イベントリスナーのアタッチや、サーバーが中断した箇所からの再開)に使用するシリアライズ済みデータペイロードを送信します。再フェッチは不要です。サーバーHTMLが正しく見えても、ハイドレーションが成功したこと、クライアント側ナビゲーションが同じコンテンツを再現すること、またはペイロードが古くなっていないことを証明するわけではありません。初回読み込みでは問題なく見えても、クライアント側ルート変更後に壊れる場合、それはレンダリングモードの問題ではなく、ハイドレーション/ペイロードの問題です。
  • <ClientOnly> とブラウザ限定コンテンツ。 何かを <ClientOnly> でラップする(ブラウザAPI依存のウィジェットで一般的)と、たとえ他の部分がユニバーサルルートであっても、サーバーレスポンスからはその部分が欠落します。メインコンテンツ、重要なリンク、メタタグがクライアント限定の境界内に入ってしまうと、生のHTMLのみを読むクローラーやAIボットは、レンダリングモードの設定に関係なくそれらを見逃します。レンダリングモードの設定だけでなく、実際のレスポンスを検査してください。
  • ステータスコードとリダイレクトは自己証明ではありません。 ブラウザでレンダリングされるNuxtエラーページや、navigateTo()/コンポーザブル駆動のリダイレクトは、それ自体では直接のサーバーレスポンスが送信したHTTPステータスを証明しません。Googleのガイダンスは、意味のあるステータスコードがクロールとインデックスに重要であると明示しています。クライアントレンダリングされたエラーページが表示するものではなく、curl -I で実際のヘッダーを確認してください。

これはどれもユニバーサルレンダリングに反対する議論ではありません。「HTMLがサーバーレンダリングされている」ことが最初のチェックであり、最後のチェックではないというリマインダーです。

Nitro、デプロイプリセット、キャッシュ境界

Nuxtのサーバー出力は Nitro によって構築され、Nitroはターゲットとするデプロイプリセット(Nodeサーバー、Cloudflare、Vercel、Netlify、静的、その他)に応じて異なるコンパイルを行います。これはSEOにとって重要です。プリセットとアダプターは、利用可能なランタイムAPI、キャッシュ動作、ストリーミングサポート、リージョナルデプロイ、ファイルシステムアクセスが異なる可能性があるためです。あるプリセットで動作するルートルールやサーバーハンドラーが、別のプリセットでも同じように動作するとは限りません。想定せずに明示的にテストする価値がある2つの結果を以下に示します。

  • キャッシュキーと無効化はルート固有であり、自動ではありません。 swrisr のルートルールは出力をキャッシュして再生成しますが、間違ったキャッシュキー、欠落した無効化、またはデプロイプラットフォームによって設定されたキャッシュヘッダーにより、クローラーに古い、パーソナライズされた、または一貫性のないHTMLが配信される可能性があります。routeRules 設定だけでなく、ライブURLの実際のレスポンスエージと Cache-Control/Age ヘッダーを確認してください。
  • 本番環境のパリティはステージングの動作では保証されません。 ローカル開発やプレビューデプロイでルートが正しくレンダリングされても、本番プリセットが同じ出力を生成するとは限りません。サーバールート、リダイレクト、エラーハンドリングはNitroのサーバーレイヤーに存在し、そのレイヤーがターゲットによって最も異なる可能性が高い部分です。レンダリングモードを検証するのと同じように、デプロイ変更後は本番URLを直接テストしてください。

メタタグ: useSeoMeta() と useHead()

Nuxtのヘッド管理はUnhead上で動作し、異なる目的のために2つのコンポーザブルを提供します。

useSeoMeta()SEOおよびソーシャルメタタグ用 に使用するものです。フラットで型安全なAPIで、型付きパラメータを備えています。 Evidence for this claim useSeoMeta is a typed Nuxt API for SEO and social meta tags. Scope: Current Nuxt composable. Confidence: high · Verified: Nuxt: useSeoMeta これは、name を使用すべきところで property を使用するという古典的なOpen Graphのバグを回避するのに役立ちます。

useSeoMeta({
  title: 'My Page Title',
  ogTitle: 'My Page Title',
  description: 'Concise page-specific description with the key information first',
  ogDescription: 'Concise social description tailored to this page',
  ogImage: 'https://mysite.com/og-image.png', // must be an absolute URL
  twitterCard: 'summary_large_image',
})

useHead() は、スクリプト、リンクタグ、ボディ属性、タイトルテンプレートなど、その他すべてのための汎用ヘッドツールです。

useHead({
  titleTemplate: '%s · My Site Name',
  htmlAttrs: { lang: 'en' },
})

信頼できるレイヤリングパターンは次のとおりです。nuxt.config.ts で静的デフォルト(charset、viewport、favicon)→ app.vue でサイト全体のタイトルテンプレートとグローバルなOGデフォルト → ページコンポーネントで useSeoMeta() によるページ固有のオーバーライド。よくあるバグは、ページではなくレイアウトuseSeoMeta() を置くことで、特定のページタグが汎用タグで上書きされることです。また、検索エンジンは初期ロードを読むため、SEOメタは一般的にリアクティブである必要はありません。useServerHead() はクライアント側の再実行をスキップします。

どのAPIか、そしてそれが実際に何を証明するか:

APIスコープリアクティブ?出力について何を証明するか
useSeoMeta()フラットで型付けされたSEO/ソーシャルメタのみはい(デフォルト)型付けされたプロパティを正しく設定する — ルートが一意、正規、インデックス可能であることを証明するわけではない。そのロジックは自分で持つ必要がある
useHead()<head> 内のすべて — スクリプト、リンク、属性、タイトルテンプレートはい(デフォルト)一般的なヘッド制御。同じ注意点 — APIの使用は正しいサーバーレスポンスの証明にはならない
useServerHead() / サーバーのみの呼び出し上記と同じいいえ — サーバーのみ、クライアントの再実行をスキップタグがサーバーHTMLに一度だけ含まれることを確認する。クライアントナビゲーションで再設定されるかは確認しない(そこに依存する場合)

これらのコンポーザブルのいずれかを呼び出すと、APIが実行されたことがわかりますが、それ自体では、直接のサーバーレスポンスやクライアント側のルート変更が実際に何を出力するかはわかりません。「useSeoMeta() を呼び出した」だけでなく、View Source や curl で確認してください。

@nuxtjs/seo モジュールエコシステム(Harlan Wilton)— オプション、コアではない

Nuxtコアは、sitemap、robots.txt、OG画像生成、Schema.orgを標準では提供しません。これらはNuxt自身のプリミティブ(useHeaduseSeoMeta、ルートルール、レンダリングモード)の外にあります。コミュニティはそのギャップをHarlan Wiltonの @nuxtjs/seo で埋めています。これは別途インストールするサードパーティの包括パッケージ(nuxtseo.com、現在v5.x、積極的にメンテナンスされ、Nuxt 3,16+ と Nuxt 4 を対象)で、6つのモジュールをバンドルしています。これをインストールすると、sitemap、robots、OG画像、スキーマの生成が得られますが、それ自体ではルートに対して出力が正しいことを保証しません。他のものと同じ方法で生成物を検証してください。

モジュール機能
@nuxtjs/robotsrobots.txt + メタロボット + X-Robots-Tag ヘッダー
@nuxtjs/sitemapページ + 動的ルートからの自動XMLサイトマップ
nuxt-og-image動的OG画像(Vueテンプレート → 画像)
nuxt-schema-orgSchema.org JSON-LD構造化データ
nuxt-seo-utils正規URL、パンくずリスト、デフォルト
nuxt-link-checkerビルド時の壊れたリンク検出

npx nuxt module add seo でバンドル全体をインストールするか、個別のモジュール(npx nuxt module add sitemap robots)を取得します。知っておくべきいくつかの動作:

  • @nuxtjs/sitemappages/ ディレクトリと動的ルートから自動生成し、50 000 URLを超えると自動的にサイトマップインデックスに分割し、i18n多言語サイトマップをサポートし、組み込みのIndexNowサポートがあります。正しく設定すべき点:Googleは changefreqpriority を無視します。正確な lastmod だけが重要で、しかもコンテンツが実際に変更された場合のみです。
  • @nuxtjs/robotsrobots.txt、ロボットメタタグ、X-Robots-Tag ヘッダーを生成します。そしてデフォルトでは非本番環境で全クローラーを拒否します。これはまさにヘッドレスビルドを悩ませるステージングインデックス化の落とし穴です。また、ボットごとのルールも提供するので、GPTBotだけをブロックし、他のボットには影響を与えないようにできます(意図的に行ってください — AIクローラーをブロックすると、あなたを引用しなくなります)。
  • nuxt-seo-utils は正規URLを処理し、便利なことにトラッキングパラメータ(utm_*fbclidgclid)を正規URLから自動的に削除します。

nuxt/image と Core Web Vitals

@nuxt/image は画像モジュールです。自動レスポンシブ srcset、最新フォーマット(WebP/AVIF)、CDNプロバイダーによる組み込み最適化、遅延読み込みを提供します。SEO価値の大部分を担う2つのルール:

  • LCP画像を遅延読み込みしないでください。 ヒーロー画像は即時読み込み(eager)にするべきです。遅延読み込みすると、Largest Contentful Paint(LCP)が遅れます。
  • 必ず widthheight を設定して、ブラウザがスペースを確保し、Cumulative Layout Shift(CLS)の影響を受けないようにしてください。
<NuxtImg
  src="/hero.jpg"
  width="1200"
  height="630"
  alt="Descriptive alt text"
  :loading="isHeroImage ? 'eager' : 'lazy'"
  format="webp"
/>

2026年の目標値(p75)は、LCP ≤ 2,5秒、INP ≤ 200ms、CLS ≤ 0,1です。Nuxtアプリでは、ハイドレーションによる入力遅延が発生するため、INPが悪化しがちです。これはまさにNuxt Islandsと<NuxtIsland>が解決するためのものです。

Nuxt ContentとSEO

@nuxt/content(Markdown/MDXコンテンツモジュール)を使用している場合、@nuxtjs/seoとの統合は簡単ですが、順序に関する注意点が1つあります。モジュール配列では@nuxtjs/seo@nuxt/contentの前に読み込んでください。その後、コンテンツのfrontmatter(titledescriptionrobotsogImageschemaOrg)でSEOを設定し、コンテンツ取得後にuseSeoMeta()を使って[slug].vueテンプレートに反映できます。これはヘッドレスCMSパターンのNuxtネイティブ版であり、「プラグインが行っていたことを再構築する」という同じ規律が適用されます。

よくあるNuxt SEOの間違い

  1. インデックスさせたいコンテンツにSPAモード(ssr: false)を使用する。 最もコストがかかる間違いであり、AIクローラーから見えなくなる原因です。
  2. OG画像に相対URLを使用する。 ogImageは絶対URLでないと、ソーシャルプレビューが壊れます。
  3. ページではなくレイアウトでuseSeoMeta()を使用する — 汎用タグがページ固有のタグを上書きします。
  4. レンダリングされたHTMLを確認しない — ソースの表示 ≠ DevTools ≠ Googleがレンダリングしたもの。URL Inspectionを使用してください。
  5. robots.txtでJS/CSSをブロックする — Googleはブロックされたファイルからレンダリングしません。
  6. 公開後にステージングのnoindex/disallowをそのままにする(または逆に、@nuxtjs/robotsがデフォルトで非本番環境をブロックすることを忘れて、本番は問題ないのにカスタム環境がブロックされる理由がわからない)。
  7. LCP画像を遅延読み込みする — LCPが悪化します。
  8. 画像にwidth/heightがない — CLSが発生します。
  9. サイトマップにchangefreq/priorityを含める — Googleはこれらを無視します。lastmodだけが重要です。
  10. 動的レンダリングに頼る。 Googleはこれを非推奨としています — “dynamic rendering is a workaround and not a long-term solution” (翻訳) 「動的レンダリングは回避策であり、長期的な解決策ではありません」 — そして、設定したエンジンにしか対応せず、BingやすべてのAIクローラーを見逃します。NuxtではSSRとSSGがすでにクローラーに完全なHTMLを提供するため、動的レンダリングは不要です。

llms.txtとAEO

llms.txtはプレーンテキストファイルで、robots.txtのいとこにあたり、AIツールがコンテンツをナビゲートするのに役立ちます。nuxt-llmsモジュールは、Nuxt Contentから/llms.txt/llms-full.txtを自動生成します。2025年後半時点で、その主な利用者はMCPサーバーやAIコーディングツール(Cursor、Claude Code)であり、ChatGPTやPerplexityが直接利用するわけではありません。ドキュメントサイトや技術ブログに最も有用で、eコマースやニュースサイトにはあまり役立ちません。ドキュメント/開発者サイトであれば追加する価値がありますが、それ以外では優先事項ではありません。

位置づけ

Nuxt SEOは、実際にはJavaScript SEOをNuxt独自の規約を通じて具体的に適用したものです。また、Nuxtフロントエンドがヘッドレスバックエンドからデータを取得する場合、ヘッドレスCMSのSEOトピックと大きく重なります。原則は変わりません。Nuxtは優れたデフォルト設定と、それを実装するための強力なモジュールエコシステムを提供するだけです。

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.