mcpField
V
vtex-io-storefront-theme-app

vtex-io-storefront-theme-app

github.com/vtex開発471.0k 回インストール2 週間前に更新
リポジトリ

vtex-io-storefront-theme-app について

VTEX IOのストアフロントテーマアプリで、ページブロックの構成、カスタムルートの定義、Site Editorで編集可能なコンテンツの設定を行うスキルです。テーマアプリ、コンポーネントアプリ、マーチャント管理コンテンツの役割も整理します。

主な機能

  1. 01ページのブロックツリーとテンプレートの構成
  2. 02ストアフロントのカスタムルート定義
  3. 03Site Editorで編集可能なプロパティの設定
  4. 04ブロック参照とアプリのメジャーバージョン確認
  5. 05テーマ継承とバージョン移行の計画

活用シーン

  1. 01ストアのホームや商品ページのレイアウト作成
  2. 02ページコンテキストを伴うカスタムルートの追加
  3. 03Site Editorでマーチャントがページ内容を編集
  4. 04ブロック欠落やテーマのメジャーバージョン変更リスクの確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/vtex/skills --skill vtex-io-storefront-theme-app

インストール後、Claude Code で/vtex-io-storefront-theme-appを入力して読み込まれたか確認します。

詳細

ストアフロントテーマアプリ

このスキルを使用する場合

ストアフロントを構成するアプリ、つまりストアのページツリー、カスタムルート、サイトエディターの表示領域を管理するテーマアプリを扱う際に、このスキルを使用してください。

  • vendor.store-theme、またはページを提供する store ビルダーを持つアプリのスキャフォールディング
  • store/blocks.json または store/blocks/ 以下のテンプレート別ファイルの追加・変更
  • store/routes.json へのカスタムルートの追加・変更
  • store.home、store.product、store.search、store.custom、またはネイティブページテンプレートのブロックツリーの構成
  • vtex.store-theme などのベーステーマの拡張またはオーバーライド
  • 変更内容がテーマアプリ、コンポーネントアプリ、アプリ設定のどこに属するかの確認

以下の場合は、このスキルを使用しないでください。

  • コンポーネントアプリで新しいブロックを登録する場合(store/interfaces.json) — vtex-io-render-runtime-and-blocks を使用してください
  • ブロックの背後にある React コンポーネントを実装する場合 — vtex-io-storefront-react を使用してください
  • master でテーマアプリのインストール済みバージョンを変更する場合 — vtex-io-storefront-theme-versioning を使用してください
  • ローカライズされた文字列の場合 — vtex-io-messages-and-i18n を使用してください

判断ルール

  • テーマアプリは、manifest.json で store ビルダーを宣言する通常の VTEX IO アプリです。React コードを含むことはほとんどなく、コンポーネントアプリやベーステーマが宣言するブロックを組み合わせます。
  • テーマアプリは通常 vtex.store-theme であるベーステーマを manifest.json#dependencies で宣言し、ベーステーマが提供するすべてのページテンプレート、ブロック宣言、デフォルトコンテンツを継承します。
  • store/blocks.json(または store/blocks/ 以下のテンプレート別ファイル)は、ブロック ID を参照して、ページテンプレートごとのブロックツリーを定義します。ブロック ID はコンポーネントアプリの store/interfaces.json に由来し、宣言元アプリの MAJOR バージョンごとにスコープされます。
  • store/routes.json はカスタムストアフロントルートを定義し、ページコンテキスト(store.custom、store.product、store.search など)に紐付けます。ネイティブルート(/、/{slug}/p、検索)はベーステーマに由来するため、再宣言する必要はほとんどありません。
  • store/contentSchemas.json は、サイトエディターで編集可能なブロックのプロパティを宣言します。マーチャントがこれらのプロパティに加えた変更は vtex.pages-graphql に保存され、テーマアプリの MAJOR バージョンを含むキーで管理されます。
  • ストアフロントの動作を変更できる場所は3つあります。意識して選択してください。
    1. テーマアプリの store/ JSON — 構成、ルート、デフォルトコンテンツ、許可される子要素を扱います。プロモート後、すべての買い物客に直ちに反映されます。
    2. コンポーネントアプリのコード — ブロックの React による動作を扱います。コンポーネントアプリ独自のバージョンリリースサイクルでリリースされます。
    3. サイトエディター — テーマのデフォルトの上書きとして、マーチャントが管理するコンテンツを扱います。vtex.pages-graphql に保存され、宣言元アプリのインストール済みメジャーバージョンごとにスコープされます。
  • ベーステーマをフォークするより、拡張することを優先してください。ベーステーマをフォークすると、上流のバグ修正も含め、すべてのブロック、ルート、テンプレートに対する責任を永久に自分のアプリが負うことになります。
  • ストアフロントページはブロックのツリーです。末端はコンポーネントブロック、枝はコンテナブロック(flex-layout.row、flex-layout.col など)です。デザイン上可能な限りツリーを浅く保ってください。深いツリーはレンダリングとコンテンツの負荷を増大させます。
  • vtex-io-storefront-theme-versioning の意味では、テーマアプリはコンテンツを保持するアプリです。インストール済みのメジャーバージョンは、このアプリが宣言したブロックに対してマーチャントがこれまでに保存した、サイトエディターのすべての変更について、プラットフォームが使用するキーの一部になります。そのバージョン契約は開発者向けではなく、マーチャント向けとして扱ってください。

厳守事項

制約:テーマアプリでは store ビルダーとベーステーマを宣言する必要があります

ストアフロントのテーマアプリは、manifest.json#builders に "store" を宣言し、すべての標準ページテンプレート、ブロック、ルートを明示的に引き受けるのでない限り、ベーステーマ(通常は vtex.store-theme)に依存する必要があります。

重要な理由

store ビルダーがないと、store/ 配下のファイルは一切処理されず、テーマはストアフロントに何も追加しません。ベーステーマがない場合、アプリはすべての標準ページテンプレート(store.home、store.product、store.search など)を一から宣言する必要があり、その後のメンテナンスも永久に担うことになります。

検出方法

テーマアプリに store/blocks.json または store/routes.json が含まれているのに、マニフェストの builders に "store" が宣言されていない場合は、作業を中断してビルダーを追加してください。マニフェストの dependencies または peerDependencies に vtex.store-theme(または別のベーステーマ)が含まれておらず、明示的な理由もない場合は、作業を中断して、そのアプリがすべての標準テンプレートを引き受ける意図があることを確認してください。

正しい例

{
  "vendor": "acme",
  "name": "store-theme",
  "version": "1.0.0",
  "title": "ACME Store Theme",
  "builders": {
    "store": "0.x",
    "messages": "1.x"
  },
  "dependencies": {
    "vtex.store-theme": "2.x",
    "acme.product-widgets": "0.x"
  }
}

誤った例

{
  "vendor": "acme",
  "name": "store-theme",
  "version": "1.0.0",
  "builders": {
    "messages": "1.x"
  },
  "dependencies": {}
}

store/ ファイルはディスク上に存在しますが、プラットフォームはそれらを無視し、テーマは何も継承しません。

制約:store/blocks.json のブロック ID は、インストール済みアプリで登録されたブロックを参照する必要があります

store/blocks.json(またはテンプレートごとのファイル)で参照されるすべてのブロック ID は、プラットフォームがレンダリング時に解決する MAJOR バージョンと一致する、インストール済みアプリの interfaces.json で宣言されている必要があります。解決できないブロック ID があると、GraphQL レイヤーで Missing block エラーが発生し、ページが表示できなくなります。

重要な理由

vtex.pages-graphql は、インストール済みアプリを検索して [email protected]:block-id を照合し、ブロック ID を解決します。宣言元のアプリがインストールされていない場合、またはマーチャントのコンテンツ作成時とは異なるメジャーバージョンでインストールされている場合、リゾルバーからはブロックが存在しないものとみなされ、ページのレンダリングに失敗します。

検出方法

store/blocks.json がブロック ID を参照している場合、manifest.json#dependencies にあるアプリのいずれかが、依存関係に記載されたメジャーバージョンの範囲で store/interfaces.json にそのブロックを宣言していることを確認してください。依存関係が [email protected] の場合、ブロックはそのアプリの 5.x 系ではなく、0.x 系に存在する必要があります。

正しい例

// manifest.json
{
  "dependencies": {
    "vtex.store-theme": "2.x",
    "acme.product-widgets": "0.x"
  }
}
// store/blocks.json
{
  "store.product": {
    "children": [
      "flex-layout.row#product-main",
      "acme-related-products"
    ]
  },
  "acme-related-products": {
    "props": { "limit": 8 }
  }
}
// [email protected] ships store/interfaces.json with:
{
  "acme-related-products": {
    "component": "RelatedProducts"
  }
}

誤った例

// manifest.json depends on [email protected]
// but store/blocks.json references a block that only exists in @5.x
{
  "store.product": {
    "children": ["acme-new-related-products"]
  }
}

レンダリング時のリゾルバーが Missing block [email protected]:acme-new-related-products を返し、ページの表示に失敗します。

制約:store/routes.json のカスタムルートは、実在するページコンテキストとテンプレートに紐付ける必要があります

store/routes.json の各エントリーでは、有効な path と context(または store.product などの標準ページ ID に組み込まれたコンテキストを利用すること)を設定し、ブロックツリーに存在するテンプレート(ページ ID 自体、または store/blocks.json で宣言された store.custom#<id>)を指定する必要があります。

重要な理由

解決可能なテンプレートがないルートエントリーでは、何もレンダリングされません。コンテキストが誤っているルートエントリー(たとえば、カスタムの法人向けページを store.product として指定した場合)は、誤ったデータリゾルバーを実行し、クラッシュしたり、商品データが空で返されたりします。

検出方法

store/routes.json の各ルートについて、次の点を確認してください。(a)path が標準の VTEX パスと衝突しないこと、(b)紐付けられたページ ID が store/blocks.json のキーとして存在すること、(c)context がページで実際に必要なデータと一致すること。

正しい例

// store/routes.json
{
  "store.custom#about": {
    "path": "/institucional/sobre",
    "context": "vtex.store-resources/InstitutionalPageContext"
  }
}
// store/blocks.json
{
  "store.custom#about": {
    "blocks": ["rich-text#about-body"]
  }
}

誤った例

// store/routes.json
{
  "store.custom#about": {
    "path": "/p/sobre"
  }
}

パス /p/sobre が標準の PDP ルート形式と衝突しており、context が宣言されておらず、store/blocks.json に対応する store.custom#about テンプレートもありません。

推奨パターン

推奨されるテーマアプリの構成:

acme.store-theme/
├── manifest.json                     # store builder, base theme dependency
├── messages/                         # localized strings (separate skill)
└── store/
    ├── blocks.json                   # global block declarations
    ├── routes.json                   # custom routes
    ├── contentSchemas.json           # Site Editor-editable props
    └── blocks/                       # per-template block trees
        ├── home.jsonc
        ├── product.jsonc
        ├── search.jsonc
        ├── category.jsonc
        └── custom/
            ├── about.jsonc
            └── stores.jsonc

推奨される store.home の構成:

{
  "store.home": {
    "blocks": [
      "flex-layout.row#home-hero",
      "shelf#home-best-sellers",
      "rich-text#home-newsletter"
    ]
  },
  "flex-layout.row#home-hero": {
    "children": ["image#hero-banner"]
  },
  "image#hero-banner": {
    "props": {
      "src": "/arquivos/home-hero.png",
      "alt": "Promotional banner"
    }
  }
}

推奨されるカスタムの機関向けルート:

// store/routes.json
{
  "store.custom#about": {
    "path": "/institucional/sobre",
    "context": "vtex.store-resources/InstitutionalPageContext"
  }
}
// store/blocks/custom/about.jsonc
{
  "store.custom#about": {
    "blocks": ["flex-layout.row#about-body"]
  },
  "flex-layout.row#about-body": {
    "children": ["rich-text#about-copy"]
  },
  "rich-text#about-copy": {
    "props": {
      "text": "About ACME — see Site Editor for the live copy."
    }
  }
}

推奨される Site Editor で編集可能な領域:

// store/contentSchemas.json
{
  "rich-text#about-copy": {
    "type": "object",
    "properties": {
      "text": {
        "type": "string",
        "title": "Body copy",
        "widget": { "ui:widget": "textarea" }
      }
    }
  }
}

text に対するマーチャントの編集内容は、テーマアプリの MAJOR バージョンを含むキーで vtex.pages-graphql に保存されます。メジャーバージョンを上げるとそのコンテンツに何が起こるか、および updateThemeIds ミューテーションを使った移行方法については、vtex-io-storefront-theme-versioning を参照してください。

よくある失敗パターン

  • vtex.store-theme に依存せずフォークしてしまい、以後、上流のブロック修正やルート追加が一切反映されなくなる。
  • store/blocks.json で、依存関係のバージョン範囲が許容するものとは異なるメジャーバージョンの宣言元アプリに存在するブロック ID を参照する。
  • 2 つの異なるアプリで同じブロック ID を宣言し、レンダリング時の解決が非決定的になる。
  • contentSchemas.json を用意せずに、Site Editor で編集可能な文言を store/blocks.json の props に直接置き、マーチャントが変更できないようにする。
  • 対応する store.custom#<id> テンプレートを store/blocks.json に追加せず、store/routes.json にカスタムルートを追加する。
  • テーマアプリのバージョンを開発者向けのものとして扱い、「整理」のためにメジャーバージョンを上げる。その結果、新しいメジャーバージョンにはマーチャントのコンテンツがなくなり、プロモート前に [email protected] で updateThemeIds による移行が必要になる(vtex-io-storefront-theme-versioning を参照)。
  • React コンポーネントのコードを専用のコンポーネントアプリではなくテーマアプリに置くことで、ブロックの宣言と利用が混在し、再利用が複雑になる。
  • 運用データや購入者固有のデータをテーマの store/ ファイルに保存する。テーマは全体に適用されるため、購入者単位またはセグメント単位のデータは別の場所に置く必要があります。

レビューチェックリスト

  • manifest.json で store ビルダーが宣言されていますか?
  • テーマはベーステーマに依存していますか?それとも、ネイティブテンプレートを全面的に所有することが明示され、意図されていますか?
  • store/blocks.json のすべてのブロック ID は、インストール済みアプリの適切なメジャーバージョンにある実際の interfaces.json エントリーに解決されますか?
  • store/routes.json のすべてのエントリーに有効な path と context があり、store/blocks.json に対応するテンプレートがありますか?
  • マーチャントが編集できる文言や画像フィールドは、props にハードコードせず、contentSchemas.json を通じて公開されていますか?
  • React コンポーネントはテーマアプリではなく、専用のコンポーネントアプリに置かれていますか?
  • 予定している変更によって、このコンテンツを保持するアプリのメジャーバージョンを上げる必要が生じないか、チームで検討しましたか?

関連スキル

  • vtex-io-storefront-theme-versioning — master にインストールされるこのテーマアプリのバージョンを安全に変更する方法が質問の場合に使用します。
  • vtex-io-render-runtime-and-blocks — ブロック ID が React コンポーネントになる仕組みや、コンポーネントアプリがテーマで利用するブロックを宣言する方法が質問の場合に使用します。
  • vtex-io-storefront-react — ページへの組み込みではなく、ブロックの React 実装が質問の場合に使用します。
  • vtex-io-app-contract — テーマアプリのマニフェスト契約で宣言すべき内容や、ベーステーマおよびコンポーネントアプリとの連携が質問の場合に使用します。

参考資料

  • Store Framework — テーマアプリがブロックとテンプレートからページを組み立てる方法です。
  • Using Components — ベーステーマやコンポーネントアプリのブロックを参照する方法です。
  • Themes — テーマアプリの構成と vtex.store-theme との関係です。
  • Routes — カスタムストアフロントルートを宣言し、ページコンテキストに関連付ける方法です。
  • Making a Custom Component Available in Site Editor — contentSchemas.json と Site Editor の画面について説明します。

コメント