{"product_id":"2026-09-14","title":"【Horizon】メタフィールドで追加した情報を、構造化データ(JSON-LD)にも動的に反映する","description":"\u003cp\u003e\u003cstrong style=\"color:#e0301e;\"\u003e【なぜ今、構造化データか】\u003c\/strong\u003e Shopifyは2026年、エージェンティックコマース向けにUCP（Universal Commerce Protocol）という専用の商品情報取得口を用意しました。AIエージェントが専用のAPIエンドポイント経由で価格・在庫・商品詳細を取得できる仕組みです。ただしUCPは、そのエージェント側が明示的にプロトコルを実装している場合にしか使われません（リクエストごとにJSON-RPC形式・エージェントプロファイルの提示が必須）。UCPに対応していない検索エンジンのクローラーや、ページを直接読みにいくAIエージェントは、引き続きページ上の構造化データ（schema.org \/ JSON-LD）を頼りにします。\u003c\/p\u003e\n\u003cp\u003eこの点は海外の構造化データ専門家も指摘しています。\u003cbr\u003e\n\u003cem\u003e\"Structured data remains the main foundation. Before an AI agent can buy a product or book a service, it has to find it.\"\u003c\/em\u003e（構造化データは引き続き土台であり、AIエージェントが商品を購入する前に、まずそれを見つけられる必要がある）\u003c\/p\u003e\n\n\u003cp\u003e\u003cstrong style=\"color:#e0301e;\"\u003e【対応テーマ】このTIPSはHorizon限定です。\u003c\/strong\u003e ブロックの中から「同じセクション内にある既存のld+jsonタグ」を探し当てる仕組み上、Horizonの\u003ccode\u003esections\/product-information.liquid\u003c\/code\u003eという特定のファイル構成を前提にしています。Dawnなど他のテーマでは、構造化データを出力しているファイル・セクション構成が異なるため、そのままでは動作しません（テーマごとに、構造化データがどのセクションの中にあるかを確認し、コードを調整する必要があります）。\u003c\/p\u003e\n\n\u003cp\u003e\u003cspan\u003e前回のTIPS（\u003ca href=\"\/products\/2026-09-13\"\u003e商品ごと・カテゴリごとに折りたたみ行の内容を出し分ける方法\u003c\/a\u003e）で、商品メタフィールドとメタオブジェクトを使って表示を出し分けられるようになりました。ただしこれはあくまで「見た目」の話で、検索エンジンやAIエージェントが読み取る構造化データ（schema.org \/ JSON-LD）には反映されません。このTIPSでは、そのメタフィールドの内容を、構造化データにも動的に反映する方法を紹介します。\u003c\/span\u003e\u003c\/p\u003e\n\n\u003cp\u003e\u003cstrong style=\"color:#e0301e;\"\u003e【重要】表示内容と構造化データは、必ず同じ値から生成すること。\u003c\/strong\u003e 「AIエージェント向けに、表示とは別の説明文を用意する」という設計は避けてください。Googleは構造化データについて「ページに実際に表示されている内容の忠実な反映でなければならず、ユーザーに見えない内容をマークアップしてはならない」という方針を明言しています。今回の実装は、表示に使っているのと同じメタフィールド・メタオブジェクトの値をそのまま構造化データに流用するため、この原則を自然に満たします。\u003c\/p\u003e\n\n\u003cp\u003e\u003cimg alt=\"表示している内容が、そのまま構造化データ(JSON-LD)にも入る\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0733\/0381\/8491\/files\/2026-09-14_1.png?v=1789305777\" class=\"zoomable-image\" style=\"max-width: 100%; height: auto;\"\u003e\u003c\/p\u003e\n\n\u003cdiv class=\"divider\"\u003e\u003c\/div\u003e\n\n\u003ch3\u003eなぜHorizon標準の仕組みだけでは足りないか\u003c\/h3\u003e\n\u003cp\u003e\u003cspan\u003eHorizonの構造化データは \u003ccode\u003e{{ closest.product | structured_data }}\u003c\/code\u003e という1行のフィルターで生成されています。このフィルターは価格・在庫・variantなどを含む完成済みのJSON文字列を返しますが、そのまま返すだけなので、あとから項目を追加することができません。かといってLiquidには文字列をJSONとして読み直すフィルター（他言語での\u003ccode\u003eJSON.parse\u003c\/code\u003e相当）が存在しないため、Liquid単体でこの文字列を分解・再構成することもできません。\u003c\/span\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cspan\u003eまた、この出力先である\u003ccode\u003e\u0026lt;script type=\"application\/ld+json\"\u0026gt;\u003c\/code\u003eタグ自体は\u003ccode\u003esections\/product-information.liquid\u003c\/code\u003eというコアファイルの中にありますが、そこにidを振るような修正は不要です。新規ブロックの中で\u003ccode\u003edocument.currentScript\u003c\/code\u003e（実行中のscript要素自身）を取得し、\u003ccode\u003e.closest('.shopify-section')\u003c\/code\u003eで同じセクション内を辿れば、コア側に一切手を加えずに既存のld+json scriptタグを特定できます。ただしこの仕組み上、ブロックの設置場所は「商品情報」セクションの中でなければいけません（別のセクションに置くと、同じセクション内にld+jsonが見つからず、何も反映されないまま静かに終了します）。\u003c\/span\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cspan\u003eもう一方の「追加したいプロパティ」側は、DOM上の並び順（隣接している等）には依存していません。JSONアイランドに\u003ccode\u003eid=\"schema-extra-properties-{{ block.id }}\"\u003c\/code\u003eという一意のidを振り、\u003ccode\u003edocument.getElementById\u003c\/code\u003eで直接特定しているため、同じセクション内に他のブロック（script要素を含むもの）がいくつ増えても、他のブロックがこのブロックの前後どこに配置されても、正しく自分自身のIDだけを見つけます。\u003c\/span\u003e\u003c\/p\u003e\n\n\u003cp\u003e\u003cimg alt=\"仕組み：1つのメタフィールドが表示と構造化データの2箇所に反映される\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0733\/0381\/8491\/files\/2026-09-14_2.png?v=1789305786\" class=\"zoomable-image\" style=\"max-width: 100%; height: auto;\"\u003e\u003c\/p\u003e\n\n\u003ch3\u003e解決策：ブラウザ側でJSON-LDにマージする\u003c\/h3\u003e\n\u003cp\u003e\u003cspan\u003eフィルターの出力はそのまま残し、別途「追加したいプロパティ」だけをLiquidでJSONとして出力しておき、ページ読み込み時にJavaScriptで両者をマージします。Googleは「レンダリング後のDOMに存在する構造化データを処理できる」ことを公式に明言しており、この方法でもリッチリザルト・AIエージェントの両方に正しく認識されます。\u003c\/span\u003e\u003c\/p\u003e\n\u003cp\u003e・schema.orgのProduct型には「メタフィールドの追加情報」専用のプロパティが無いため、この用途の受け皿として用意されている \u003ccode\u003eadditionalProperty\u003c\/code\u003e（\u003ccode\u003ePropertyValue\u003c\/code\u003eの配列）に格納します。\u003c\/p\u003e\n\u003cp\u003e・ただし、動的生成された構造化データはクロール頻度・信頼性がやや落ちる、ともGoogleは明記しています。価格や在庫のような頻繁に変わる情報はフィルターの静的出力のまま触らず、今回のように補足情報だけを後付けする範囲であれば影響は限定的です。\u003c\/p\u003e\n\n\u003ch3\u003e設定手順\u003c\/h3\u003e\n\u003cp\u003e\u003cstrong style=\"color:#e0301e;\"\u003e【ポイント】コアファイル（sections\/product-information.liquid等、Horizon本体のファイル）は一切変更しません。\u003c\/strong\u003e 新規のプライベートブロックを1つ追加し、テーマエディタから「商品情報」セクションにブロックとして加えるだけで完結します。\u003c\/p\u003e\n\u003cp\u003e◆1. コードエディタで \u003ccode\u003eblocks\u003c\/code\u003e ディレクトリに \u003ccode\u003eschema-additional-property.liquid\u003c\/code\u003e を新規作成し、コードを貼り付けます（コードはご購入後に表示されます）。\u003c\/p\u003e\n\n\u003cp\u003e\u003cimg alt=\"新規作成：blocks\/schema-additional-property.liquid\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0733\/0381\/8491\/files\/2026-09-14_3_73c92191-21a6-4770-91e6-da778b54da0e.png?v=1789335809\" class=\"zoomable-image\" style=\"max-width: 100%; height: auto;\"\u003e\u003c\/p\u003e\n\n\u003cp\u003e◆2. テーマエディタで商品ページを開き、「商品情報」セクションの「ブロックを追加」から「構造化データに追加情報を反映」ブロックを追加します。\u003cstrong style=\"color:#e0301e;\"\u003e「商品情報」セクションの中であれば、どこに配置しても構いません\u003c\/strong\u003e（他のブロックの前後どちらでも、ネストの深さも問いません）。見た目には何も表示されないブロックです。\u003c\/p\u003e\n\n\u003cp\u003e◆3. コード先頭の設定部で、参照するメタフィールドのキーを自分のストアのものに書き換えます。\u003c\/p\u003e\n\u003cp\u003e・\u003ccode\u003eschema_product_description\u003c\/code\u003e：リッチテキスト型の商品メタフィールドを\u003ccode\u003emetafield_text\u003c\/code\u003eフィルターでプレーンテキスト化\u003cbr\u003e\n・\u003ccode\u003eschema_category_guide_text\u003c\/code\u003e：メタオブジェクト参照メタフィールドの先にある、リッチテキストフィールドを同様にプレーンテキスト化\u003c\/p\u003e\n\u003cp\u003e\u003cstrong style=\"color:#e0301e;\"\u003e【注意】リッチテキスト型のメタフィールドは、\u003ccode\u003e.value\u003c\/code\u003eや\u003ccode\u003estrip_html\u003c\/code\u003eフィルターだけでは正しくプレーンテキスト化されません。\u003c\/strong\u003e（実際に検証中、値がリッチテキストの生データ構造のまま出力されてしまう不具合が発生しました。）必ず \u003ccode\u003emetafield_text\u003c\/code\u003e フィルターを使ってください。\u003c\/p\u003e\n\n\u003ch3\u003e動作確認の方法\u003c\/h3\u003e\n\u003cp\u003e反映後、商品ページを開いてブラウザの「検証（Inspect）」でDevToolsを開き、Consoleで以下を実行すると、マージ後の内容を直接確認できます。\u003c\/p\u003e\n\u003cp\u003e\u003ccode\u003eJSON.parse(document.querySelector('script[type=\"application\/ld+json\"]').textContent).additionalProperty\u003c\/code\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cstrong style=\"color:#e0301e;\"\u003e【注意】「ページのソースを表示」（view-source）ではこの内容は確認できません。\u003c\/strong\u003e マージはJavaScriptがページ読み込み後にDOMを書き換える処理のため、サーバーが返す初期HTMLには表れません。必ず「検証」またはコンソールで、実行後のDOMを確認してください。\u003c\/p\u003e\n\n\u003ch3\u003eカスタマイズのポイント\u003c\/h3\u003e\n\u003cp\u003e\u003cspan\u003e今回は商品メタフィールドとメタオブジェクト参照の2種類を例にしましたが、\u003ccode\u003eadditionalProperty\u003c\/code\u003eの配列に項目を追加すれば、他のメタフィールドも同様の要領で反映できます。\u003c\/span\u003e\u003c\/p\u003e\n\n\u003ch3\u003e注意点\u003c\/h3\u003e\n\u003cp\u003e・動的生成した構造化データは、Google自身がクロール頻度・信頼性の面でやや不利になり得ると明記しています。価格・在庫等の変動が激しい情報はこの方式に含めないでください\u003cbr\u003e\n・値が空のメタフィールドは\u003ccode\u003eadditionalProperty\u003c\/code\u003e自体を出力しないため、余計な空文字列がスキーマに残ることはありません\u003c\/p\u003e\n\n\u003cp\u003e\u003cspan\u003e商品ごと・カテゴリごとに折りたたみ行の表示を出し分ける方法自体は\u003ca href=\"\/products\/2026-09-13\"\u003eこちらのTIPS\u003c\/a\u003eで紹介しています。\u003c\/span\u003e\u003c\/p\u003e\n\n\u003cp\u003e\u003cspan\u003e参考:\u003cbr\u003e\n\u003ca href=\"https:\/\/developers.google.com\/search\/docs\/appearance\/structured-data\/generate-structured-data-with-javascript\" target=\"_blank\" rel=\"noopener\"\u003eGoogle公式：Generate Structured Data with JavaScript\u003c\/a\u003e\u003cbr\u003e\n\u003ca href=\"https:\/\/developers.google.com\/search\/docs\/appearance\/structured-data\/sd-policies\" target=\"_blank\" rel=\"noopener\"\u003eGoogle公式：General Structured Data Guidelines\u003c\/a\u003e\u003cbr\u003e\n\u003ca href=\"https:\/\/shopify.dev\/docs\/agents\" target=\"_blank\" rel=\"noopener\"\u003eShopify公式：Build commerce agents with UCP\u003c\/a\u003e\u003cbr\u003e\n\u003ca href=\"https:\/\/www.structureddata.co.uk\/blog\/structured-data-webmcp-ucp-agentic-ecommerce\" target=\"_blank\" rel=\"noopener\"\u003eHow Structured Data, WebMCP, and UCP Form the Trinity of Agentic E-Commerce\u003c\/a\u003e\u003c\/span\u003e\u003c\/p\u003e\n\n","brand":"STORE DOJO","offers":[{"title":"Default Title","offer_id":49305294995707,"sku":null,"price":0.0,"currency_code":"JPY","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0733\/0381\/8491\/files\/2026-09-14_614d443c-0520-4543-8dad-e09f3d02e211.jpg?v=1789306342","url":"https:\/\/store-dojo.com\/products\/2026-09-14","provider":"STORE DOJO","version":"1.0","type":"link"}