🧭 SPAは本当にSEOに強いのか?「2段階インデックス」の現実と、Rails Hotwireという最適解

🧭 SPAは本当にSEOに強いのか?「2段階インデックス」の現実と、Rails Hotwireという最適解

· · 5分で読めます

Advertisement

「モダンなWeb開発ならSPA(Single Page Application)一択」

そう信じて走り出したプロジェクトが、リリース後にSEOで苦戦する
これは今も現場で繰り返されている、静かな事故です。

確かに Googlebot は進化しました。
しかし、

「JavaScriptを実行できる」こと

「HTMLと同じコストで即座に理解できる」こと

この二つは、まったく別物です。

SPA(特にCSR)が抱える構造的なSEOリスク と、
それを回避しつつモダンなUXを実現する Rails + Hotwire のアプローチを、
技術的エビデンス付きで解説します。


🕷️ Googlebot と SPA の現実

Two-wave Indexing(2段階インデックス)

Googleのクロール処理には Two-wave Indexing(2段階インデックス) という仕組みがあります。
これが、SPAのSEOを難しくしている根本原因です。

⏱️ なぜ「遅延」が発生するのか

🟢 第1波(Initial Crawl)

🟡 待機(Rendering Queue)

🔵 第2波(Rendering)

問題はこの 待機時間 です。

サイト規模やクロールバジェット次第では、
数時間〜数日 のタイムラグが発生します。

ニュース、EC、キャンペーンページでは、
この遅延は静かに、しかし確実に致命傷になります。


🔍 証拠:Googlebotが見ている世界

❌ 典型的なReact CSR実装

// ❌ SEOに弱い典型的なCSR実装
import { useState, useEffect } from "react";
export default function NewProductPage() {
  const [product, setProduct] = useState(null);
  useEffect(() => {
    fetch("/api/products/latest")
      .then(res => res.json())
      .then(data => {
        setProduct(data);
        document.title = data.name;
      });
  }, []);
  if (!product) return <div>Loading...</div>;
  return (
    <article>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
    </article>
  );
}

第1波のGooglebot視点(curl)

<!DOCTYPE html>
<html>
  <head>
    <title>React App</title>
  </head>
  <body>
    <div id="root">Loading...</div>
    <script src="/static/js/main.js"></script>
  </body>
</html>

結論

第1波の時点で、
このページは 「Loading...」としか書かれていない
コンテンツとして認識されます。


🥪 「サンドイッチ構造」の代償

この問題を解決するため、
Next.js(SSR) + Rails API
という BFF / サンドイッチ構造 がよく採用されます。

SEOは確かに改善します。
しかし、引き換えに失うものは 開発の単純さ です。

🧨 失われるRailsの生産性

「SEOのため」の選択が、
速度ではなく、摩擦を増やす 結果になることも珍しくありません。


🌱 Rails Hotwireという「第三の選択肢」

Hotwireの思想は極めて明快です。

JSONではなく、完成されたHTMLを送る
(HTML Over The Wire)

これにより、次の二面性を同時に満たします。


🧩 コードで見る Hotwire の解決策

🧠 Controller(いつものRails)

# app/controllers/products_controller.rb
class ProductsController < ApplicationController
  def show
    @product = Product.find(params[:id])
  end
end

🧾 View(完成されたHTML)

<article id="product_content">
  <h1><%= @product.name %></h1>
  <p><%= @product.description %></p>
</article>
📄 curlで確認する完全なHTML
$ curl https://example.com/products/1
<!DOCTYPE html>
<html>
  <head>
    <title>すごい新商品 | My Shop</title>
  </head>
  <body>
    <article id="product_content">
      <h1>すごい新商品</h1>
      <p>これは革命的な商品です...</p>
    </article>
  </body>
</html>

Two-wave indexing の待ち時間はゼロ
Googlebotは、アクセスした瞬間にすべてを理解します。


⚡ なぜSPAのように速いのか?

🚀 Turbo Drive の仕組み

Turbo Drive が裏で静かに働きます。

  1. リンククリック
  2. Turboが通常遷移をキャンセル
  3. fetchで次ページHTML取得
  4. <body> を丸ごと差し替え

JSやCSSは再読み込みされません。

結果として、

この「正体」が、Hotwireの強さです 🌱

🧭 結論:技術選定の羅針盤

SPAは悪ではありません。

これらではSPAが最適解です。

しかし、もしあなたのプロジェクトが:

ならば、

Rails + Hotwire は妥協案ではなく、
最も合理的で、持続可能な最適解

です。

「何を足すか」ではなく、
「何を増やさないか」

その視点こそが、
スケールする設計への近道になります 🚦

Advertisement
#turbo#rails#hotwire#spa#seo#twowave#googlebot#mpa#アキテクチャ#モダンweb開発
Advertisement