概要

関わっている案件でLaravel11からLaravel12へアップデートする必要があり、事前確認としてLocal環境でアップデートを試してみたところ、過去に構造化マークアップを導入した際に追加した記述の中で使用していた@context 属性が Blade テンプレートエンジンのディレクティブとして誤認識されエラーが発生するという問題が発生したので調べてみた。

問題の詳細

Laravel 12では、Blade テンプレートエンジンが以下のディレクティブに対応しました:

  • @context() – 新しい Blade ディレクティブ

この変更により、JSON-LD などの構造化マークアップに含まれる @context 属性が自動的に Blade ディレクティブとして解析されるようになりました。

問題の詳細

例えば以下のような記述例の際に当現象が発生する模様

<script type="application/ld+json">
{
  "@context": "https://schema.org", ← この @context をBlade が @context() ディレクティブとして誤認識するようになってしまった
  "@type": "Product",
  "name": "Example Product"
}
</script>

対策

調べてみたところ、以下のような対策が挙がった。

1. エスケープ処理

@context@@context にエスケープして、Blade が @context() ディレクティブとして誤認識するのを回避

<script type="application/ld+json">
{
  "@@context": "https://schema.org",
  "@type": "Product",
  "name": "Example Product"
}
</script>

2. JSONを格納するPHP配列を定義し、 json_encode() で出力

PHPでJSON変数を先に定義し、それを使用する

@php
$structuredData = [
  "@context" => "https://schema.org",
  "@type" => "Product",
  "name" => "Example Product"
];
@endphp

<script type="application/ld+json">
  {{ json_encode($structuredData, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) }}
</script>

3. @verbatim ブロックを使用する

Blade の処理を完全にスキップするディレクティブを使用

@verbatim
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Example Product"
}
</script>
@endverbatim

4. Raw ブロックを使用する

新しい Blade 構文を使用(Laravel 12推奨とのこと)

<script type="application/ld+json">
  {!! json_encode([
    "@context" => "https://schema.org",
    "@type" => "Product",
    "name" => "Example Product",
  ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) !!}
</script>

採用した対策

実際のマークアップの記述は項目が多く、動的に値を埋め込む部分もあるため、影響の少ないエスケープ処理か、PHP配列+json_encode()で出力する方法が妥当なところかなと感じたので、今回はエスケープ処理を採用して対応。

まとめ

Laravel 12 へのアップデートに伴い @context ディレクティブをサポートしたことで構造化マークアップ内の @context 属性が誤認識される問題が発生するようになったが、エスケープ処理やPHP配列を使用した出力など対策方法が存在するので要件に応じて適切な方法を選択し対応しましょう。