---
title: "編集アーキテクチャ"
slug: "editing-architecture"
abstract: "SitecoreAIページビルダーがページレンダリングをどのようにアプリに委ねているか、アプリが公開しなければならない編集エンドポイント、メタデータ編集モードの仕組みを説明します。"
---
# 編集アーキテクチャ

> !注**このドキュメントの改善にご協力ください**フレームワークに依存しないドキュメントは現在開発中です。コンテンツ改善の提案があれば、このページの下部で **フィードバック** を共有してください。

SitecoreAIのページビルダーは、コンテンツ作成者にページ編集のためのWYSIWYGキャンバスを提供しますが、サイトのページをレンダリングするわけではありません。代わりに、iframe内でアプリを読み込むことで、レンダリングをアプリに委ねます。ビジュアル編集を有効にすると、アプリがページのHTMLをレンダリングし、構造的メタデータをHTMLに埋め込み、その結果をページビルダーに返します。

## ハンドシェイク終端

アプリとページビルダーが安全に通信するためには、ページビルダーが呼び出す2つの編集APIエンドポイントを公開する必要があります:

-   /api/editing/config - ページビルダーはまず、アプリがメタデータ編集モードをサポートしているか確認し、登録されたコンポーネントのリストを取得するために GET および OPTIONS リクエストを行います。
-   /api/editing/render - エディター内の各ページビューに対して、ページビルダーはiframeのsrcをURL内の関連パラメータでこのエンドポイントに設定して編集キャンバスを読み込みます。ブラウザが GET リクエストを出し、アプリはそのパラメータを使ってSitecoreから編集レイアウトデータを取得し、メタデータコードブロックを埋め込んだままページ全体HTMLレンダリングし、完全なHTMLドキュメントをブラウザに返します。

このドキュメントに示されている /api/editing/configおよび /api/editing/renderパスは固定値ではなく、従来のデフォルトであることにご注意ください。

-   ページビルダーがconfigエンドポイントのために呼び出すURLは、対応するアイテムの**サーバー側レンダリングエンジンアプリケーションURL**[フィールドに保存されている](https://doc.sitecore.com/sai/ja/developers/sitecoreai/environment-editing-hosts-and-rendering-hosts/configure-an-external-editing-host.html)/sitecore/system/Settings/Services/Rendering Hosts/\*。ほとんどの実装ではこれを変更する必要はありません。
-   configエンドポイントとは異なり、renderエンドポイントのパスはレンダリングホストアイテム上で設定できません。

両エンドポイントは通常「 SITECORE\_EDITING\_SECRET」と呼ばれる共有秘密によって保護されています。

> !重要共有秘密の検証に加え、リクエストのOriginヘッダーを確認し、CORSの応答をSitecoreのページビルダードメイン(例: https://pages.sitecorecloud.ioやhttps://app.sitecorecloud.io)に制限してください。コンテンツ・セキュリティ・ポリシー frame-ancestorsディレクティブも同様に設定し、ページビルダーだけがiframeでアプリを読み込めるようにしてください。実装例としては、「 [視覚編集を有効にする](https://doc.sitecore.com/sai/ja/developers/sitecoreai/introduction-to-framework-agnostic-sitecore-development/visual-editing/enable-visual-editing.html) 」ウォークスルーに示されているCORSの扱い方をご覧ください。

## 編集の仕組み

コンテンツ作成者がページビルダーでページを開くと、以下のことが起こります。

1.  ページビルダーは、編集ホストに初めて接続したときにアプリの/api/editing/configエンドポイントを呼び出します。例えば、ページビルダーが最初に読み込まれた時や、編集ホストを切り替えたときなどです。アプリはシークレットを検証し、"editMode": "metadata"とアプリがレンダリングできるコンポーネント名を宣言するJSONドキュメントを返します。 このドキュメントは、[レガシーchromesモード](https://doc.sitecore.com/sai/en/developers/jss/latest/jss-sai/architecture-and-apis-for-integrating-jss-next-js-apps-with-sitecore-editors.html)に代わる現代の編集モードであるmetadataモードのみを扱っています。
2.  Pageビルダーはiframeを読み込み、キャンバスを開きます。iframeの src はアプリの /api/editing/render エンドポイントを指し示し、編集中のページ、サイト、言語、バージョンを識別するクエリパラメータがあります。レンダーエンドポイントは常に断片ではなく完全なHTMLドキュメントを返すことに注意してください。
3.  パラメータを使って、アプリは [プレビュー GraphQL API](https://doc.sitecore.com/sai/ja/developers/sitecoreai/introduction-to-framework-agnostic-sitecore-development/content-rendering/the-preview-and-delivery-graphql-apis.html)から編集レイアウトデータを取得します。レスポンスにはフィールド値、コンポーネントツリー、各フィールドの編集専用メタデータが含まれます。
4.  アプリは完全なHTMLドキュメントをレンダリングし、すべてのプレースホルダー、コンポーネント、フィールド値の周囲に<code>メタデータブロックを埋め込み、Sitecore提供されたキャンバススクリプトも<head>に含まれています。 <head> には、編集キャンバス上でページが正しいスタイルやスクリプトでレンダリングされるように、アプリ独自のCSSやJavaScriptアセットを含める必要があります。これは公開サイトと同様にです。ブラウザがこのHTMLをiframeに読み込むと、Sitecore提供のキャンバススクリプトが編集オーバーレイを起動し、 <code> マーカーをスキャンして画面上の要素をSitecoreの項目にマッピングします。

## 設定応答

/api/editing/configエンドポイントは以下の形状のJSON文書を返す必要があります。

{
 "editMode": "metadata",
 "components": "Promo", "Title", "RichText", "...",
 "packages": {}
}

財産

概要

editMode

メタデータ編集モードを使うには "metadata" が必要です。

components

あなたのアプリがレンダリングできるSitecoreコンポーネント(レンダリング)の名前のリスト。各名前はSitecore内の対応するレンダリングアイテムの名前と一致しなければなりません。

packages

パッケージ版のオプションマップ。カスタムアプリ用に空のオブジェクトのままにしてください。

ページビルダーはcomponentsを使って、アプリからどのレンダリングをページに追加できるかを決定します。このリストに含まれていないレンダリングはSitecoreに存在できますが、コンテンツ作成者はアプリで編集中にページビルダーを通じてページに追加することはできません。

## 編集GraphQLクエリ

アプリでコンテンツをレンダリングする際は、layoutクエリを使ってルートパスで[レイアウトデータを取得し](../content-rendering/layout-query-and-response.md)ます。編集クエリは2つの点で異なります。

-   ルートパスではなく、アイテムIDでページを調べます。
-   さらに2つのHTTPヘッダーを送信します。

### アイテムID

ページビルダーは、ルートパスではなくSitecoreアイテムID(GUID)でページを識別します。編集クエリはitem(path: $itemId) を使い、GUIDを直接渡します。また、レイアウトデータと一緒にサイト辞書も取得し、編集HTMLをレンダリングする際にコンポーネントが使用する翻訳キーを利用できるようにします。

query EditingQuery(
 $siteName: String!
 $itemId: String!
 $language: String!
 $version: String
 $pageSize: Int = 1000
 $after: String
) {
 item(path: $itemId, language: $language, version: $version) {
 rendered
 }
 site {
 siteInfo(site: $siteName) {
 dictionary(language: $language, first: $pageSize, after: $after) {
 results { key value }
 pageInfo { endCursor hasNext }
 }
 }
 }
}

renderedフィールドは、コンテンツレンダリングに使われるレイアウトクエリと同じJSON形状のレイアウトデータを返します。$pageSize変数と$after変数は、大規模な辞書を持つサイトではカーソルベースのページ付けをサポートします。

サイト辞書は、Sitecoreで管理される翻訳文字列のフラットキーバリューストアです。例えば、ボタンラベル、フォームのプレースホルダー、その他のUIテキストなど、コンテンツ作成者がコンポーネントフィールドコンテンツとは独立して翻訳するものなどです。辞書はレイアウトデータとともに返され、コンポーネントレンダラーがレンダリング時に変換キーを解決する必要があるアプリで利用可能です。ビジュアル [編集を有効](./enable-visual-editing.md) にするサンプルアプリは辞書を取得しますが、変換可能なUI文字列を含まないため、使用はしません。

### HTTPヘッダー

編集クエリは標準のx-sitecore-contextidヘッダーに加えて2つのHTTPヘッダーを送信します。

ヘッダー

概要

sc\_editMode

"true"の場合、プレビュー GraphQL APIは下書き(未公開)コンテンツを返し、レイアウトデータ内のすべてのフィールドオブジェクトにmetadataプロパティを追加します。  
  
ページビルダーが編集モードでページを開くときにこの値を "true" に設定し、プレビューモードで "false" してください。

sc\_layoutKind

返すべき [レイアウトタイプ](/sai/en/users/sitecoreai/edit-the-layout-of-an-item.html) は shared または finalです。  
  
デフォルトは finalです。

sc\_editMode: "true"が各フィールドオブジェクトに追加するmetadataプロパティにより、インライン編集が可能になります。ページビルダーは、コンテンツ作成者がどのフィールドとやり取りしているかを特定するためにこれを使用します。このヘッダーがなければmetadataがなく、フィールドクロームは有効化できません。

フレームワーク内のクエリ実装の詳細については、「 [ビジュアル編集を有効にする](./enable-visual-editing.md#retrieve-editing-layout-data-using-graphql)」をご覧ください。

## メタデータ編集モード

メタデータ編集モードはSitecoreの最新のエディター統合戦略です。プレースホルダー、レンダリング、フィールドにはレイアウトサービスが提供するメタデータを使用します。ページビルダーはこのメタデータを使って編集可能なレイアウト要素を特定し、コンポーネントの選択や並べ替えを可能にします。

メタデータ編集モードでは、アプリがすべてのプレースホルダー、コンポーネント、フィールドを2つの <code> 要素でラップします。ページビルダーのJavaScriptはこれらを読み取り、レンダリングされたHTMLのどの部分がどのSitecore項目やフィールドに対応しているかを特定します。これにより、ページビルダーは編集可能な地域の地図を作成できます。そのマップは、コンテンツ作成者がコンポーネントをクリックし、その選択ハンドルを確認し、新しい位置にドラッグして、そのコンポーネントのフィールドパネルを開くためのものです。

以下は、エディタ内でレンダリングされたHTMLの見た目の例です:

<!-- Placeholder open -->
<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="open" id="headless-main\_<ROUTE\_UID>"></code>

<div data-placeholder="headless-main">
 <!-- Component open -->
 <code type="text/sitecore" chrometype="rendering" class="scpm" kind="open" id="<UNIQUE\_COMPONENT\_ID>"></code>
 <div>
 <!-- Field open -->
 <code type="text/sitecore" chrometype="field" class="scpm" kind="open">{"type":"field render","fieldId":"...","fieldType":"Single-Line Text",...}</code>
 <h1>Hello World</h1>
 <!-- Field close -->
 <code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>
 </div>
 <!-- Component close -->
 <code type="text/sitecore" chrometype="rendering" class="scpm" kind="close"></code>
</div>

<!-- Placeholder close -->
<code type="text/sitecore" chrometype="placeholder" class="scpm" kind="close"></code>

id属性について以下の点に注目してください。

-   プレースホルダー id 属性は <placeholderKey>\_<parentUID>であり、 parentUID はプレースホルダーを所有する親レンダリングまたはルートアイテムの uid です。
-   コンポーネント id 属性は、レイアウトデータから得たコンポーネント自身の uid です。

ページビルダーはこれらのIDを使って、画面上の各要素を特定のSitecore項目に接続し、コンテンツ作成者が変更を加えた際に何を更新すべきかを把握しています。

## フィールドクローム

コンポーネントレベルの<code> ブロックでは、ページビルダーがコンポーネントを選択し、並べ替えることができます。コンテンツ作成者がフィールド値をインラインで編集できるようにするには、例えば見出しや段落を直接クリックしてタイプするなど、各フィールド値をそれぞれ独立した<code>ブロックのペアでラップする必要があります。この追加レイヤーはコンテンツ編集可能なサーフェスを有効化し、コンテンツ作成者がテキストをクリックしてタイプできるようにします。

GraphQLリクエストでsc\_editMode: "true"を設定すると、レイアウトデータには各フィールドにmetadataオブジェクトが含まれます。冒頭のコードブロックはそのメタデータをテキスト内容としてシリアートします。ページビルダーがページを読み込むと、各フィールド値に対してコンテンツ編集可能なサーフェスを起動するために以下のブロックを読み込みます。

<!-- Field open - serialized field metadata is the text content -->
<code type="text/sitecore" chrometype="field" class="scpm" kind="open">{"type":"field render","fieldId":"...","fieldType":"Single-Line Text",...}</code>
<span>Hello World</span>
<!-- Field close -->
<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>

フィールドクロームがなければ、キャンバス内でコンポーネントを選択できますが、コンテンツ作成者はフィールドをインラインで編集することはできません。つまり、テキストをハイライトすることはできますが、タイピングには影響がありません。

## 脚本編集

コンポーネントとフィールドのChromeは、ページビルダーにページ上の*内容*を伝えます。編集スクリプトはページとの*やり*取り方法を教えてくれます。

sc\_editModeが"true"されると、編集レイアウトデータ応答のsitecore.contextオブジェクトには、ページビルダーがキャンバス内での編集操作を可能にするために使用するフィールドが含まれています。/api/editing/renderエンドポイントは、アプリ固有のCSSやJavaScript資産に加えて、ページビルダーに戻すHTMLにこれらのフィールドを埋め込む必要があります。

-   clientScripts - JavaScript URLの配列。ページビルダーはこれらのスクリプトをキャンバスのiframeに読み込み、編集オーバーレイやインタラクションハンドラーを取り付けます。それらがなければ、キャンバスはページを読み込みますが、編集イベントの受信・送信はできません。
-   clientData\- アプリが特定のIDを持つタグに書き込む必要がある2つの値のマップ<script>
    -   hrz-canvas-state - キャンバスがどの項目、サイト、言語、レイアウトモードを表示しているかを編集スクリプトに伝えるJSONオブジェクト。
    -   hrz-canvas-verification-token - iframeとページビルダー間のメッセージpostMessage認証トークン。それがなければ、ページビルダーはiframeからの信号を無視します。

アプリがレンダリングするHTMLは、これらを <head> と <script> タグに埋め込む必要があります。

<!-- JavaScript bundles provided by Sitecore (exact URLs vary per environment) -->
<script type="text/javascript" src="https://..."></script>

<!-- Canvas state that the Page builder reads on load -->
<script id="hrz-canvas-state" type="application/json">{"itemId":"...","siteName":"...",...}</script>

<!-- Verification token for the canvas communication channel -->
<script id="hrz-canvas-verification-token" type="application/json">TOKEN</script>

アプリがレンダリングするHTMLには、<body>にid="jss-hrz-editing"を含む<script>要素も含めなければなりません。ページビルダーは、アプリがメタデータ編集モードで応答していることを確認するために、この要素をチェックします:

<script id="jss-hrz-editing" type="application/json">{}</script>

## レンダリングエンドポイントのクエリパラメータ

ページビルダーが編集キャンバスを読み込むと、iframe srcをアプリの /api/editing/render URLに設定します。その後、ブラウザは以下のクエリパラメータでGETリクエストを行います。

クエリパラメータ

概要

secret

必須。  
  
必ず一致 SITECORE\_EDITING\_SECRET。

sc\_site

必須。  
  
サイト名。  
  
例: my-site

sc\_itemid

必須。  
  
編集中のページのSitecoreアイテムID(GUID)です。

sc\_lang

必須。  
  
ページの言語コード。  
  
例: en

route

必須。  
  
ページへのルート経路。  
  
例: / と /products

mode

必須。  
  
edit 編集キャンバス用、またはプレビューモード用に preview 。

sc\_version

任意です。  
  
アイテムバージョン。数値のバージョン番号、または latest を使って、最新のバージョンを明示的にリクエストしてください。セットが解除されている場合、アイテムの最新バージョンが取得されます。

sc\_variant

任意です。  
  
パーソナライズバリアントID。

sc\_layoutKind

任意です。  
  
[レイアウトタイプ](/sai/en/users/sitecoreai/edit-the-layout-of-an-item.html)はsharedまたはfinal。  
  
デフォルトは finalです。

### 例示リクエスト

以下はページビルダー GETレンダリングエンドポイントに対して行うリクエストの例です:

/api/editing/render?secret=<SITECORE\_EDITING\_SECRET>&sc\_site=my-site&sc\_itemid=54C8E9B5-0B2C-5363-8FA6-D32A3A302F51&sc\_lang=en&route=/&mode=edit&sc\_version=latest

sc\_version、sc\_variant、sc\_layoutKindのパラメータはすべて任意で省略可能です。