コンテンツへ移動

スキーマグラフ(JSON-LD)

JSON-LDは、ノード同士が参照し合う形にすると検索エンジンに伝わりやすくなります。OrganizationがWebSiteを発行し、WebSiteがWebPageを含み、WebPageがArticleについて述べるという関係です。SchemaGraphは、安定した@idで相互に結び付けたノード群を生成し、すべてのページで一貫したグラフを出力します。

ページのグラフ

php
use Rankbeam\Seo\Facades\SEO;
use Rankbeam\Seo\Services\Schema\SchemaCollection;
use Rankbeam\Seo\Services\Schema\SchemaGraph;

$seo = SEO::resolve($post);

$graph = new SchemaGraph();

$schemas = SchemaCollection::make()
    ->add($graph->organization())   // @id: {app_url}#organization
    ->add($graph->webSite())        // @id: {app_url}#website, publisher → #organization
    ->add($graph->webPage($seo));   // @id: {page_url}#webpage, isPartOf → #website

Bladeのheadまたはbody内で出力します。

blade
{!! $schemas->toScript() !!}

OrganizationとWebSiteのデータはconfig/seo.phpschema.organizationschema.website)から取得し、WebPageノードには解決済みのSEODataを反映します。

WebPageノードのinLanguageには、ページの解決済みロケールをBCP 47形式(it_ITit-IT)で設定します。ArticleSchema::fromModel()では保存済みのseo_metaのロケールを使い、WebSiteノードではschema.website.inLanguageからサイトの言語を列挙します(単一のコードまたはリスト)。schema.in_languagefalseにすると、inLanguageは一切出力されません。多言語コンテンツを参照してください。

型別のビルダー

一般的なリッチリザルトの型には、専用のビルダーがあります。

ビルダー補足
ArticleSchema::fromModel($post)モデルと設定から日付、著者、発行者を取得
ProductSchemaオファー、価格、在庫状況
BreadcrumbSchema::fromArray([...])順序付きの名前とURLの組
BreadcrumbSchema::fromModelAncestors($page)parentの連鎖をたどる(循環を防ぐ保護付き)
FAQSchema質問と回答の組
LocalBusinessSchema住所、位置情報、営業時間
OrganizationSchema独立したOrganizationノード

記事ページ全体の例です。

php
$article = ArticleSchema::fromModel($post)
    ->setPublisherOrganization(config('seo.schema.publisher.name'));

$schemas = SchemaCollection::make()
    ->add($graph->organization())
    ->add($graph->webSite())
    ->add($graph->webPage($seo))
    ->add($article->toArray())
    ->add(BreadcrumbSchema::fromArray([
        ['name' => 'Home', 'url' => '/'],
        ['name' => 'Blog', 'url' => '/blog'],
        ['name' => $post->title, 'url' => "/blog/{$post->slug}"],
    ])->toArray());

付加したスキーマと@seoSchema

解決済みのSEODataに保存されたスキーマ(たとえば、明示的なメタデータと一緒に保存したもの)は、@seoSchemaディレクティブまたはSEO::toArray()scriptセクションから出力されます。

blade
@seoSchema($post)

編集者は、Filamentフィールドパッケージの任意の構造化データセクションを使い、コードを書かずにseo_meta.schema_jsonldを設定できます。自動パンくずリストの切り替えとFAQ / Productブロックがあり、保存前にSchemaValidatorで検証されます。

エスケープ

SchemaCollection::toScript()toJson()、各レンダラー経由の出力を含め、すべてのJSON-LD出力はJSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMPでエンコードされます。タイトルやコンテンツ内の</script>でscript要素が終了することはありません。スキーマ配列を自分でjson_encodeに渡して、この処理を迂回しないでください。

rankbeam/laravel-seoはMITライセンスで公開されています。