SPAでメタタグ管理が難しくなる理由

SPAでは「head」がページごとに存在しない

SPAでメタタグ管理が難しい理由は単純です。
SPAは本来ページ単位で存在するはずの<head>を、アプリケーション起動時に1回しか読み込まないからです。

通常のWebページでは、URLごとに別のHTMLが返ります。
つまりページが変われば<title>やdescriptionも自動的に変わります。

しかしSPAではURLが変わってもページ遷移は発生しません。
ここがSEOやSNSシェアで問題を生む根本原因です。

通常のWebページでメタタグが機能する仕組み

通常のMPAでは次のようなHTMLが返ります。

<head>
  <title>商品A</title>
  <meta name="description" content="商品Aの説明">
</head>

別のURLへ移動すると、新しいHTMLが届きます。

<head>
  <title>商品B</title>
  <meta name="description" content="商品Bの説明">
</head>

ブラウザは新しい文書として扱います。
検索エンジンもこのheadを解析します。

つまりメタタグは「文書の属性」です。
本来アプリケーションの状態ではありません。

SPAではHTMLが1回しか来ない

SPAの初期レスポンスは次の形になります。

<head>
  <title>My App</title>
</head>
<body>
  <div id="app"></div>
  <script src="/app.js"></script>
</body>

その後、ユーザーが商品ページを開いても新しいHTMLは届きません。
JavaScriptがDOMを書き換えるだけです。

つまり検索エンジンやSNSクローラが受け取るheadは最初の1回だけになります。

なぜこれが問題になるのか

SEOとSNSプレビューは、次の情報をheadから取得します。

  • title
  • description
  • og:image
  • og:title

例えばSNS共有では、URLの情報を取得してカードを生成します。
SPAでメタタグを書き換えても、クローラがJavaScriptを実行しない場合、最初のtitleのままになります。

結果として次の現象が起きます。

  • すべてのページが同じタイトル
  • 商品ページなのにトップの説明文
  • SNSカードが壊れる

headを書き換えれば良いのでは?

もちろんJavaScriptで変更は可能です。

document.title = "商品A";

しかし問題は「誰が読むか」です。
ユーザーのブラウザは反映されますが、クローラは反映されない場合があります。

特にSNSクローラはJavaScriptをほとんど実行しません。
サーバから受信したHTMLのみを解析します。

head管理ライブラリが必要になる理由

そこで登場するのがhead管理ライブラリです。

役割は単なるtitle変更ではありません。
ルーティング状態とメタ情報を同期させることです。

例:ルートに応じてheadを変更

route("/product/:id", id => {
  setMeta({
    title: "商品" + id,
    description: "商品詳細"
  });
});

これによりユーザー体験は改善します。
ただしSEOはまだ解決していません。

なぜSSRがこの問題を解決するのか

SSRではURLごとにHTMLを生成します。

<head>
  <title>商品A</title>
  <meta name="description" content="商品Aの説明">
</head>

クローラはJavaScriptを実行せずに情報を取得できます。
これが「SPAはSEOに弱い」と言われる理由の一部です。

Prerenderという回避策

SPAでも対策はあります。
Prerender(事前レンダリング)です。

ビルド時にページごとのHTMLを生成します。

  • /product/1.html
  • /product/2.html

クローラにはこの静的HTMLを返し、ユーザーにはSPAを返します。
これによりメタタグ問題を回避できます。

実務で起きやすい落とし穴

最も多いのは次の誤解です。

「ブラウザでタイトルが変わっているからSEOも大丈夫」

これは危険です。
確認しているのは人間のブラウザであり、検索エンジンの挙動ではありません。

特にOGP画像が出ない問題は、ほぼメタタグ取得タイミングが原因です。

どう理解するとよいか

SPAは「アプリケーション」です。
一方メタタグは「文書の属性」です。

アプリケーションの状態変化と文書の属性は本来別物です。
SPAは文書を1回しか配布しないため、文書属性の更新と相性が悪くなります。

そのためhead管理ライブラリが必要になり、さらにSEOを考えるとSSRやPrerenderが検討対象になります。

メタタグ問題はSEOテクニックの話ではありません。
「ページ」という概念を持つWebと、「画面」という概念を持つSPAの設計差から自然に発生する現象です。