GoogleのJSON-LD解析が変更、HTMLアンエスケープは1回だけに

[レベル: 上級]

Google は JSON-LD のエスケープ処理の仕様を変更しました。
従来は二重エスケープを自動補正していましたが、標準規格に準拠し 1 回だけの処理になります。

二重エスケープの自動補正を停止

検索セントラルの LinkedIn 公式アカウントが処理変更をアナウンスしています。

パーサーを JSON などの標準仕様に準拠させるため、JSON-LD の抽出処理を変更し、HTML のアンエスケープを 1 回だけ行うようにしました。実際のところ、これは二重にエスケープされたエンティティ(&✔ など)が今後は展開されなくなることを意味します。

構造化データに JSON-LD を使用している場合は、標準の JSON エスケープ、または Unicode の 16 進エスケープ(\u0026 など)を使用するよう、コードを更新してください。

二重エスケープとは

かなり技術寄りのトピックなのでどういうことなのかを概説します。

二重エスケープ(Double Escaping)とは、本来 1 回だけエスケープ処理されるべき特殊文字や制御文字に対して、意図せずに 2 重(2 回)にエスケープ処理が適用されてしまった状態を指します。

JSON-LD で記述する HTML 内に埋め込む構造化データにおいて、今回の Google の JSON-LD 抽出処理の変更が JSON-LD の解析に影響を与える場合があります。

正常なエスケープと二重エスケープの違い

たとえば、社名アンパサンド (&) が含まれる 「株式会社 A & B」 という文字列を HTML 上の JSON-LD に記述する場合で考えます。

Unicode での 1 回のエスケープでの正しい表記はこうなります。

"name": "株式会社 A \u0026 B"

HTML文字参照を使うと、次のように記述される場合もあります

"name": "株式会社 A & B"

Google の現在の処理では、& は1回のアンエスケープによって & として扱われます。

ところが、& の先頭にある & が、システムや CMS によってさらにエスケープされてしまう場合があります。

"name": "株式会社 A & B"

これが二重エスケープの状態です。

チェックマークを表す HTML 数値文字参照 ✔ が、✔ になるのも二重エスケープの例です(JSON の Unicode エスケープでは \u2714 と表記する)。

Googlebot の処理系(パーサー)で何が起きるか?

今回の変更で、Googlebot が JSON-LD を読み込む際の「HTMLアンエスケープ処理」が 1回のみ(Single Pass) に変更されました。
これにより、解析処理に次のような差が生じます。

従来の動作:複数回アンエスケープして自動補正

  1. & を 1 回目の処理で & に展開
  2. 2 回目の処理で & をさらに & に展開
  3. 最終的に Google は 「株式会社 A & B」 と正しい文字列として認識してくれていた。

変更後の動作:1 回のみアンエスケープ

  1. & を 1 回目の処理で & に展開
  2. ここで処理が終了
  3. 最終的に Google は 「株式会社 A & B」 という、文字化けのような状態のまま認識してしまう

推奨される対応策

今後は、Unicode 16 進数表記または標準的な JSON エスケープを使うようにします。

& などの特殊文字は \u0026 のように Unicode 形式で表現します。

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "株式会社 A \u0026 B"
}

HTMLをエスケープせず、生文字のまま JSON エンコードすることも可能です。

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "株式会社 A & B"
}

1 回のみ行われる HTML アンエスケープ処理を通過しても JSON パーサーが適正に処理します。
& のままで、正しく「株式会社 A & B」として処理されます。

CMS やプラグイン、テンプレートエンジンなどのシステムの仕様により、JSON-LD の生成に二重エスケープが発生しているサイトは対応してください。