SPAのSEO

シングルページアプリケーション(React Router、Vue Router、Angular Router)をクロール可能かつインデックス可能にする方法 — アプリシェルとソフト404の問題、History APIとハッシュルーティング、SSR/プリレンダリングによるルートごとのHTML、ルートごとのcanonicalとタイトル、クライアントサイドルートのサイトマップ生成。

初回公開:2026年7月3日 · 最終更新:2026年8月20日 · Advanced
言語

シングルページアプリケーションは1つのドキュメントを読み込み、サーバーへ新しいページを要求する代わりにJavaScriptでビューを切り替えます。多くのSPAは「アプリシェル」を使い、各ルートをJavaScriptがレンダリングするまで、サーバーが1つのURL分の実際のHTMLではなく、ほぼ空のシェルを返します。ただし、これは一般的な実装の1つであり、すべてのSPAに当てはまる規則ではありません。まず、各ルートへの直接リクエストが実際に返す内容を確認してください。素のアプリシェルが問題なら、対策には2つの独立した側面があります。アドレス可能性(ハッシュや#!フラグメントではなくHistory APIを使い、各ビューに実際のURLを与えること。History APIによるソフトナビゲーションはURLとUIを変えますが、それ自体は新しいサーバーレスポンスを作りません)と、コンテンツの可用性(SSR、プリレンダリング、またはメタフレームワークにより、各URLがリクエスト時に固有のHTMLを返せるようにすること)です。さらに、各ルートのtitle、canonical、robotsの状態を直接アクセス時とレンダリング後の両方で確認し、ソフトエラーを処理します。ルーターは「見つかりません」ビューでも200を維持しがちなため、それ自体がエラーを返すURLへリダイレクトするか、レンダリング後のnoindexを追加します。ただし初期状態のnoindexはレンダリングをスキップさせる可能性があります。最後に、サイトマップ内のすべてのルートが実在するインデックス可能なHTMLを返すことを確認してください。SPA専用のサイトマップ形式はありません。

TL;DR — SPAのSEOにおける本質的なリスクは、抽象的な「JavaScript」ではなく、クライアントサイドルーティングがサーバーの応答を変えずにユーザーに見える内容を変えることです。対策には、混同されがちな2つの独立した側面があります。アドレス可能性(History API、ルートごとに固有のURL、#!フラグメントを使わないこと)と、コンテンツの可用性(SSR、プリレンダリング/SSG、またはメタフレームワーク)です。前者だけを実施すると、どのURLも同じシェルをレンダリングするだけの整然としたサイトマップができあがります。さらに、各ルートのレンダリング後のDOMに固有のcanonical、title、descriptionを設定し、200のままになるソフトエラーを処理し、サイトマップ内のすべてのルートがそれぞれ実際のHTMLを返すようにする必要があります。

SPA SEOとは実際には何か

SPAはアプリケーションアーキテクチャであり、SEOが必ず失敗する状態ではありません。 Evidence for this claim Primary standard or official documentation supporting the adjacent article claim. Scope: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Confidence: high · Verified: MDN: Single-page application サーバーレンダリング、プリレンダリング、または慎重に実装されたクライアントレンダリングによってコンテンツを公開できますが、いずれもインデックスを保証するものではありません。 Evidence for this claim Primary standard or official documentation supporting the adjacent article claim. Scope: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Confidence: high · Verified: Google: JavaScript SEO basics

これはシングルページアプリケーションに特化した詳細解説です。React Router、Vue Router、Angular Routerを使用したクライアントサイドルーティングで、最初の読み込み以降、サーバーが完全なページを送信することはありません。これは、より広範なJavaScript SEOガイド(パリティ、遅延読み込み、無限スクロール、JSレンダリング全般をカバー)や、React、Next.js、Nuxt、Angular、Vue、Svelte、Astroに関するフレームワーク別の記事と並ぶものです。ここでは、ルーティングレイヤーとそれがクロールとインデックスに与える影響のみに焦点を当てます。

素のクライアントサイドルーティングSPAがSEOで失敗する理由

1つのURL、1つのHTMLレスポンス — アプリシェル問題

Googleはこの失敗モードを正確に説明しています:“Some JavaScript sites may use the app shell model where the initial HTML does not contain the actual content and Google needs to execute JavaScript before being able to see the actual page content.” (翻訳) 「一部のJavaScriptサイトでは、初期HTMLに実際のコンテンツが含まれておらず、Googleが実際のページコンテンツを表示する前にJavaScriptを実行する必要があるアプリシェルモデルを使用する場合があります。」 素のSPAでは、「アプリシェル」がサーバーが返すすべてです。/productsを新しく取得しても、/aboutで取得するのと同じほぼ空のドキュメントが返されます。コンテンツが分岐するのは、ブラウザがJavaScriptを実行し、ルーターが表示内容を決定した後だけです。

問題の核心は一文で表せます。クライアントサイドルーティングは、サーバーが返す内容を変えずに、ユーザーに見える内容を変えます。 ソフトエラー、重複コンテンツ、titleの欠落といった後続の問題は、すべてその症状です。

サーバーはどの「ページ」がリクエストされたかを認識しない(ハッシュルーティングが失敗する理由)

従来のSPAでは、example.com/#/productsのようなURLフラグメントからビューを読み込んでいました。Googleの原文では、“A SPA may use URL fragments (for example https://example.com/#/products) for loading different views.” (翻訳) 「SPAでは、異なるビューを読み込むためにURLフラグメント(例:example.comの/#/products)を使用する場合があります。」と説明されています。これが失敗する理由は明確で、ブラウザはHTTPリクエストでフラグメント(#以降)をサーバーへ送信しないからです。サーバーには、どの「ページ」が要求されたかを知る手段がないため、ルートごとに異なるコンテンツやステータスコードを返せません。クローラーがURLを取得しても、フラグメントにかかわらず同一のHTMLを受け取ります。

これが、Googleが2015年10月に2009年のAJAXクローリング方式を正式に非推奨とした理由でもあります:“In short: We are no longer recommending the AJAX crawling proposal we made back in 2009.” (翻訳) 「要するに、2009年に提案したAJAXクローリングの提案はもう推奨していません。」 古い_escaped_fragment_回避策は、リクエスト時にフラグメントルートをサーバー側でプリレンダリングできるようにしましたが、ルーティング問題を修正するのではなく、回避策を講じたにすぎません。それに代わるGoogle自身の推奨は、以下で説明するHistory APIです。

ソフトエラー — クライアントサイドルーターはすべてに200を維持する

素のSPAでは、この問題はほぼ避けられません。クライアントサイドルーターは設計上、「見つかりません」の状態を含むすべての仮想ナビゲーションで、元のページの200ステータスを維持します。Googleも明示しています。“In a single-page application (SPA), this can be especially difficult. To prevent error pages from being indexed, you can use one or both of the following strategies.” (翻訳) 「シングルページアプリケーション(SPA)では、これは特に難しい場合があります。エラーページがインデックスされるのを防ぐには、次の戦略の一方または両方を使用できます。」 その理由についても、“When a SPA is using client-side JavaScript to handle errors they often report a 200 HTTP status code instead of the appropriate status code.” (翻訳) 「SPAがクライアントサイドJavaScriptでエラーを処理すると、適切なステータスコードではなく成功ステータスを報告することがよくあります。」と説明しています。

その結果、空のビューやエラービューが薄い200ページとしてインデックスされることになります。Googleはここで正確に2つの戦略を文書化しています:サーバーが実際の404/エラーステータスを返すURLへのリダイレクト(または完全なリクエスト)を行うか、JavaScriptでエラービューにnoindexタグを追加します。2つ目に注意してください:そのnoindexが、アプリがルートが無効だと判断した後に追加されるのではなく、最初のペイントから存在する場合、Googleがページのレンダリングを完全にスキップする原因になる可能性があります。そのため、JSが実行されるに直接リクエストが何を返すかを確認してください。後でレンダリングされたDOMに表示されるものだけを確認するのではありません。

Evidence for this claim For a client-rendered not-found view, Google documents two approaches: redirect to a URL whose server returns a 404 response, or add noindex with JavaScript; an initial noindex can cause rendering to be skipped, so raw and rendered directives require separate testing. Scope: SPAs Confidence: high · Verified: Fix Search-related JavaScript problems

共有シェルの重複 — 可能性のある原因であり、自動的な診断ではない

2つ目の、より見つけにくい失敗があります。異なるルートが同じ共有ヘッダー、ナビゲーション、フッターの定型部分だけをレンダリングし、互いの重複としてインデックス登録される場合です。Gary Illyes氏は、その発生パターンの1つを次のように説明しています。“I have a bunch of emails in my inbox where the issue is that the centerpiece took forever to load, so rendering timed out (my most likely explanation) and we were left with a bunch of pages that only had the boilerplate. With only the boilerplate, those pages are dups.” (翻訳) 「受信トレイには、中心となるコンテンツの読み込みに時間がかかりすぎてレンダリングがタイムアウトし(私が最も可能性が高いと考える説明)、定型部分しかないページが大量に残ったという相談が多数あります。定型部分しかなければ、それらのページは重複です。」 対策については、“Try to restructure the js calls such that the content (including marginal boilerplate) loads first.” (翻訳) 「コンテンツ(周辺の定型部分を含む)が最初に読み込まれるよう、JavaScript呼び出しの構成を変えてみてください。」 (LinkedInの投稿経由で伝えられたもので、自動検証が難しいため、信頼性の高い二次情報として扱います。)

Illyes氏が「最も可能性の高い説明」と表現しており、確定診断とはしていない点は、文字どおり受け取るべきです。「レンダリングのタイムアウト」は症状だけでは診断できません。ルートの重複コンテンツをタイムアウトのせいにする前に、リクエスト単位の証拠(直接取得した応答)、レンダリング後の証拠(中心となるコンテンツが存在するか)、Search Consoleの証拠(重複やインデックス登録のシグナル)が必要です。バグ、ブロックされたリソース、本当に同一のシェルといった別の原因も考えられます。また、設計の基準にできる固定の公開タイムアウトはありません。Googleの基本ドキュメントでは、ページが*“may stay on this queue for a few seconds, but it can take longer than that,”* (翻訳) 「このキューに数秒間留まる場合がありますが、それ以上かかることもあります」とされ、具体的な時間は示されていません。想定したレンダリングキューの長さに合わせるのではなく、実際の所要時間にかかわらず主要コンテンツができるだけ早く読み込まれるようにしてください。

修正方法: ルートごとに実際の HTML を取得する

完全な修正には、人々が常に混同している2つの独立した部分があります:

  1. URL アドレス可能性 — History API、ルートごとに一意の URL、フラグメントなし。
  2. コンテンツの可用性 — SSR、静的プリレンダリング/SSG、またはメタフレームワーク。

#1 だけを行うと、クリーンで共有可能な URL が得られますが、それらはすべて同じ空白のシェルを返します。 実際にインデックスさせたいルートには、両方が必要です。

ただし、これはどこにでも SSR を追加するという普遍的な義務ではありません。SSR とプリレンダリングは、クローラーが JavaScript の実行に成功することへの依存度を減らすものであり、サイトが技術的に SPA であるからといって、即座に必須になるわけではありません。特定のルートのアーキテクチャを選択する前に、3つのことを確認してください: そのルートがそもそもランキング対象になる必要があるか(内部管理パネルは対象外)、直接の JS なしのリクエストがすでに何を返すか(一部のセットアップはすでに意味のある HTML を送信します)、そして実際に満たす必要があるクローラーはどれか(Google は JS をかなり確実にレンダリングしますが、Bing とほとんどの AI クローラーはそれほどでもありません — 以下を参照)。これらのチェックをすでに通過している CSR は、サイトが SPA であるという理由だけで SSR に変更する必要はありません。

サーバーサイドレンダリング (SSR)

サーバーはリクエストごとにアプリを実行し、そのルートの完全に形成された HTML を返し、その後クライアントがそれをライブの SPA に「ハイドレート」します。これは最も堅牢なオプションです。クローラーは最初のフェッチで完全なコンテンツを取得でき、JS の実行は不要だからです。

静的プリレンダリング / SSG

リクエストごとにレンダリングする代わりに、デプロイ時にすべてのルートの HTML を事前にビルドします。 ユーザーごとに変わらないコンテンツに最適です。私自身の JavaScript SEO に関する記事から: あらゆる種類の SSR、静的レンダリング、およびプリレンダリングのセットアップは、検索エンジンにとって問題ありません。避けるべきことは、コンテンツをクライアントのみのレンダリングの背後にロックしたままにすることです。

または: 手作りせずにメタフレームワークを使用する

新しいビルドの場合、正直な推奨事項は、React-Routerのみ、またはVue-Routerのみのクライアントサイドルーティングを手作りしないことです。メタフレームワーク(Next.js、Nuxt、SSRパッケージを備えたAngular、SvelteKit、Remix)を使用すると、SSR/SSGとルートベースのメタデータが標準で提供され、このカテゴリの問題全体を回避できます。(これらのそれぞれについて、このサイトで詳細な解説があります。)裏面についても正直に述べてください:既存の手作りのSPAにSSRを後付けすることは、実際のエンジニアリング作業、つまり設定トグルではなく移行プロジェクトです。

動的レンダリングは最終手段ではなく、一時しのぎとして

クローラーには、別途レンダリングしたHTMLスナップショット(動的レンダリング)を配信できます。GoogleとBingはいずれもこれを認めています。Bingは*“recommend[s] dynamic rendering as a great alternative for websites relying heavily on JavaScript” (翻訳) 「JavaScriptに大きく依存するウェブサイトには、動的レンダリングを優れた代替手段として推奨する」* (Bingの2018年のブログからの伝聞です。後述するbingbotの能力に関する短い2つの引用は直接検証済みですが、この長い引用は今回独立して再確認していません。)としています。一方、Googleはこれが回避策だと明記しています。“Dynamic rendering was a workaround and not a long-term solution… Instead, we recommend that you use server-side rendering, static rendering, or hydration as a solution.” (翻訳) 「動的レンダリングは回避策であり、長期的な解決策ではありませんでした。代わりに、サーバーサイドレンダリング、静的レンダリング、またはハイドレーションを解決策として使用することを推奨します。」 (Googleの動的レンダリングに関するドキュメントからの伝聞です。この文言は、このサイトのより広範なJavaScript SEOガイドで引用済みの内容と一致します。) これは橋渡しであり、アーキテクチャではありません。

History API vs. ハッシュルーティング(#!

2つの状態ではなく、5つの状態

SPAルートのテストは、「機能するかどうか」が実際には5つの異なる、個別に検証可能な状態に及ぶため、混乱を招きます:

状態内容
サーバーレスポンスJSなしの新しいHTTPリクエストがURLに対して実際に取得するバイト。
レンダリングされたDOMブラウザ(またはGooglebotのレンダラー)がそのサーバーレスポンスに対してJavaScriptを実行した後に構築するもの。
検索処理Googleがサーバーレスポンスを個別にクロールし、後でページをレンダリングし、その両方に基づいてインデックスを作成する方法。
ブラウザのフルドキュメントナビゲーションURLへの実際の新しいHTTPリクエスト。サーバーレスポンスまたはステータスコードを変更できる唯一の状態。
ブラウザのソフトナビゲーション表示されるURL、ブラウザ履歴、および画面上のUIを変更するHistory API遷移(pushState/replaceState)。

誰もが混同する点:ソフトナビゲーションはURLとUIを変更しますが、それ自体では新しいHTTPレスポンスやステータスを作成しません。それはフルナビゲーション(またはcurlなどの同等の直接リクエスト)でのみ発生します。ホームページからアプリ内をクリックしてルートをテストすることはソフトナビゲーションを実行することであり、URLを直接リクエストしてテストすることはサーバーレスポンスを実行することです。両方が重要であり、それらは一致しない可能性があります。

History APIが提供するもの

Googleの推奨は明確です。“We recommend using the History API to load different content based on the URL in a SPA.” (翻訳) 「SPAでは、URLに基づいて異なるコンテンツを読み込むためにHistory APIを使用することを推奨します。」 (公開中のドキュメントでは「History API」がリンクになっているため、このディープリンクは導入部分を対象としています。) History API(pushState/replaceState)を使うと、ルーターはページ全体を再読み込みせずに、表示URLを/productsのような実在するブックマーク可能なパスへ変更できます。/#/productsのようなパスは使いません。これでアドレス可能性の側面が解決され、各ビューにサーバーが異なる応答を返せるURLが与えられます。

フラグメント/ハッシュURLがサーバーから見えない理由 — そしてGoogleからも

フラグメントはサーバーへ届かないため(前述)、各ルートにサーバーが実際に配信できるURLを与える方法はHistory APIだけです。Googleの基本ドキュメントでも、*“don’t use fragments to load different page content. The following example is a bad practice, because Googlebot can’t reliably resolve the URLs.” (翻訳) 「異なるページコンテンツを読み込むためにフラグメントを使用しないでください。次の例は、GooglebotがURLを確実に解決できないため、望ましくない方法です。」*と最低限の要件を示しています。これは私が別の記事でも書いている案内と同じです。/productsのような通常のURLを使い、/#/productsのようなハッシュURLは避けてください。GoogleはハッシュURLを確実にインデックス登録できません。

2015年の非推奨化について簡単に

ハッシュバング(#!)の時代は、Googleの2015年の投稿で終わりました:「時代は変わりました。今日では、GooglebotがJavaScriptやCSSファイルのクロールをブロックしていない限り、私たちは一般的にモダンブラウザのようにウェブページをレンダリングして理解することができます」、そして*「History APIのpushState()を使用して、より広範囲のブラウザ(および当社のシステム)へのアクセシビリティを確保できます」*。覚えておく価値のあるニュアンス:Googleは古いハッシュバングサイトを即座にインデックスから削除したわけではありません — 「私たちは一般的に#! URLをクロール、レンダリング、インデックスします」 — しかし「まだ試すことはできます」は「あなたはまだこれを行うべきです」ではありません。

各ルートを個別にインデックス可能にする

クリーンなURLと実際のHTMLがあればクロールされます。正しくインデックスされるためには、各ルートに独自のシグナルが必要です。

ルートごとのcanonicalタグ — そして「最も制限的なディレクティブ」の罠

すべてのルートには、レンダリングされたDOMに独自のrel=canonicalが必要です。罠:プレースホルダーのcanonical(またはnoindex)が生のHTMLシェルに含まれていて、JavaScriptが後でそれを上書きすることになっている場合、競合が発生する可能性があります。Googleは、生のバージョンとレンダリングされたバージョンの間の競合を、より制限的なシグナルを採用することで解決します — 以前私が述べたように、GoogleはHTMLとページのレンダリングされたバージョンの間で最も制限的なステートメントを選択します。シェルに組み込まれた迷子のnoindexや間違ったcanonicalは、JSが「修正」した後でも、ルート全体を静かに抑制する可能性があります。

JavaScriptによるルートごとのタイトルとメタディスクリプション

これらをJavaScriptで設定しても問題ありません。Googleも、“You can use JavaScript to set or change the meta description as well as the <title> element.” (翻訳) 「JavaScriptを使用して、メタディスクリプションやtitle要素を設定または変更できます」と明記しています。必要なのは、値が一瞬表示されるだけでなく、Googleが評価するレンダリング後のDOMに残ることです。ルートの変更に応じて更新される固有のtitleとdescriptionを各ページに設定してください。

ルート間の実際の<a href>リンク

ルート間のリンクには、href属性を持つ本物のアンカーを使い、<div>のクリックハンドラーは使わないでください。Googleはhrefを抽出してURLを発見するため、ルーターで移動する<div onClick>はクローラーのリンク抽出では見えません。また、ナビゲーション間でコンテンツを引き継ぐためにクライアント側の状態へ依存しないでください。Googleのレンダラーは、“does not retain state across page loads: Local Storage and Session Storage data are cleared across page loads. HTTP Cookies are cleared across page loads.” (翻訳) 「ページ読み込み間で状態を保持しません。Local StorageとSession Storageのデータはページ読み込みのたびに消去され、HTTP Cookieも消去されます。」

SPAルートのサイトマップ生成

特別な「SPAサイトマップ」形式はありません — それは会計の問題です

サイトマッププロトコルはSPAでも変わりません。実際の作業は、リストするすべてのルートが実際の、一意の、レンダリングされたHTMLに解決されることを確認することです。 500のクライアント側ルートのサイトマップは、それらのルートがすべて同じシェルを返す場合、価値がありません。したがって、サイトマップはレンダリング戦略の下流にあり、その代わりではありません。

動的/パラメータ化されたルートの処理(/product/:id

パラメータ化されたルートを持つアプリの場合、リストを手動で維持することはできません。サイトマップジェネレーターは、アプリが使用するのと同じデータソースに対して実行する必要があります — すべてのidを列挙するビルドスクリプトまたはサーバーエンドポイント — これにより、サイトマップとアプリが決して乖離しません。それらの列挙されたURLは、SSRまたはプリレンダリングされた後にのみリストする価値があります。

サイトマップをサーバーで解決可能なものと同期させる

ビルドの一部として、またはコンテンツソースに連動するスケジュールでサイトマップを再生成してください。エラーになるルート(さらに悪い場合は、200のソフトエラー)がサイトマップに残っていると、クロール予算と品質シグナルを無駄にします。

Googleが実際に見ているものをテストする

1つのURLをスポットチェックしないでください。SPA問題の要点は、ルートがブラウザでは異なるがワイヤー上では異ならない可能性があることです。したがって、生のHTMLレベルで複数のルートをテストしてください:

  • ルートごとに生のHTMLを取得する。 curlを使い(必要に応じてGooglebotのユーザーエージェントを指定)、コンテンツが共有シェルではなくURLごとに固有であることを確認します。
  • Search ConsoleのURL検査 — 複数のルートについてクロール後・レンダリング後のHTMLを比較し、ルートごとのtitle、description、canonicalが存在することを確認します。
  • エラールートが正しいシグナルを返すことを確認する。 「見つかりません」ビューは、実際のエラーステータスへリダイレクトするか、レンダリング後のDOMにnoindexを含める必要があります。

SPA SEOに関するよくある誤解

  • 「GoogleはSPAをまったくインデックス登録できない」 古い認識です。Googleは常時更新されるChromiumを実行し、通常はSPAコンテンツをレンダリングします。実際のリスクは、ソフトエラー、ハッシュルーティング、レンダリングのタイムアウト、Google以外のクローラー(Bingは信頼性が低く、多くのAIクローラーはレンダリングしない)など、より具体的です。
  • 「History APIを追加すればSPA SEOは解決する」 解決するのはアドレス可能性だけです。サーバーがすべてのルートに同じシェルを返すなら、Googleは内容を見るために引き続きJavaScriptを実行する必要があります。
  • 「ハッシュルーティングはフォールバックとしてまだ使える」 2015年に非推奨となり、それ以降も推奨されていません。
  • 「クライアントサイドレンダリングはランキング上のペナルティになる」 CSRへの直接的なペナルティはありません。影響は間接的で、レンダリングの失敗や遅延、ソフトエラー、レンダリングのタイムアウトによる重複クラスタリングが、インデックス登録される内容を減らします。
  • 「ボット向けのプリレンダリングはクローキングである」 ボットに配信する内容がユーザーに最終的に表示される内容と一致していれば、クローキングではありません。違うのはレンダリングの時点や場所であり、コンテンツではありません。
  • 「特別なSPAサイトマップ生成ツールが必要である」 特別な形式はありません。必要なのは、掲載した各ルートが実際のHTMLを返すようにすることです。

FAQ

Googleはシングルページアプリケーションをインデックスできますか? はい、各ルートが実際のURLで実際の一意のHTML(SSR/プリレンダリングによる)に解決される場合です。クライアントのみのSPAはしばしばそうではありません。

SSRが必要ですか、それともクライアントサイドレンダリングで問題ないですか? CSRはランク付けする必要のないコンテンツには機能しますが、確実にインデックスしたいものにはプリレンダリングまたはSSRを使用してください — レンダラーが時間内にJSを実行することを期待しないでください。

ハッシュ(#!)ルーティングはSEOに悪いですか? はい — フラグメントはサーバーに到達しないため、GoogleはそれらのURLを確実に解決できません。History APIを使用してください。

すべてのルートに独自のcanonicalタグが必要ですか? はい、レンダリングされたDOM内で — そして、生のシェルにそれより制限的なもの(誤ったnoindexや間違ったcanonical)が含まれていないことを確認してください。

プリレンダリングサービスはクローキングですか? いいえ、ボットに提供されるコンテンツがユーザーが見るものと一致する限り。

ルーティングを自分で構築する代わりにメタフレームワークを使用すべきですか? 新しいビルドでは、通常はそうです — Next.js/Nuxt/Angular-SSR/SvelteKitはSSR/SSGとルートごとのメタデータを無料で提供します。

なぜ私のSPAは存在しないページに対して200を返すのですか? クライアントサイドルーターが仮想ナビゲーションに対して元の200ステータスを保持するためです。実際のエラーステータスへのJSリダイレクトまたはレンダリングされたnoindexで修正してください。

Add an expert note

Pin an expert quote

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