vtex-io-storefront-theme-app
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseStorefront Theme App
店铺前端主题应用
When this skill applies
本技能的适用场景
Use this skill when working on the app that assembles the storefront — the theme app that owns the page tree, custom routes, and Site Editor surface area for a store.
- Scaffolding or any app with the
vendor.store-themebuilder that ships pagesstore - Adding or changing or per-template files under
store/blocks.jsonstore/blocks/ - Adding or modifying a custom route in
store/routes.json - Composing the block tree for ,
store.home,store.product,store.search, or any native page templatestore.custom - Extending or overriding a base theme such as
vtex.store-theme - Reviewing whether a change belongs in the theme app, in a component app, or in app settings
Do not use this skill for:
- registering a new block in a component app () — use
store/interfaces.jsonvtex-io-render-runtime-and-blocks - implementing the React component behind a block — use
vtex-io-storefront-react - changing the theme app's installed version on — use
mastervtex-io-storefront-theme-versioning - localized strings — use
vtex-io-messages-and-i18n
当您处理负责组装店铺前端的应用时,可使用本技能——即拥有页面树、自定义路由和商家Site Editor操作界面的主题应用。
- 搭建或任何带有
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.jsonvtex-io-render-runtime-and-blocks - 实现块背后的React组件——请使用
vtex-io-storefront-react - 在环境中修改主题应用的已安装版本——请使用
mastervtex-io-storefront-theme-versioning - 本地化字符串——请使用
vtex-io-messages-and-i18n
Decision rules
决策规则
- A theme app is a regular VTEX IO app with the builder declared in
store. It almost never ships React code; it composes blocks declared by component apps and by base themes.manifest.json - The theme app declares its base theme in , typically
manifest.json#dependencies, and inherits every page template, block declaration, and default content the base ships.vtex.store-theme - (or per-template files under
store/blocks.json) defines the block tree per page template by referencing block IDs. Block IDs come from the component apps'store/blocks/and are scoped by the declaring app's MAJOR version.store/interfaces.json - defines custom storefront routes and binds them to a page context (
store/routes.json,store.custom,store.product, etc.). Native routes (store.search,/, search) come from the base theme and rarely need to be redeclared./{slug}/p - declares Site Editor-editable props for blocks. Merchant edits to those props are stored by
store/contentSchemas.jsonunder a key that includes the theme app's MAJOR version.vtex.pages-graphql - Three change locations exist for storefront behavior. Pick consciously:
- Theme app JSON — composition, routes, default content, allowed children. Affects all shoppers immediately on promote.
store/ - Component app code — the React behavior of a block. Released on the component app's own version cadence.
- Site Editor — merchant-managed content overrides on top of the theme's defaults. Stored by and scoped by the declaring app's installed major.
vtex.pages-graphql
- Theme app
- Prefer extending a base theme over forking it. Forking a base theme moves the responsibility for every block, route, and template to your app forever, including upstream bug fixes.
- A storefront page is a tree of blocks. The leaves are component blocks; the branches are container blocks (,
flex-layout.row, etc.). Keep the tree as shallow as the design allows; deep trees inflate render and content footprint.flex-layout.col - The theme app is a content-holding app in the sense of . Its installed major version is part of the key the platform uses for every Site Editor change a merchant has ever saved against blocks declared by this app. Treat its version contract as merchant-facing, not developer-facing.
vtex-io-storefront-theme-versioning
- 主题应用是在中声明了
manifest.json构建器的常规VTEX IO应用。它几乎从不包含React代码;而是组合由组件应用和基础主题声明的块。store - 主题应用在中声明其基础主题,通常为
manifest.json#dependencies,并继承基础主题提供的所有页面模板、块声明和默认内容。vtex.store-theme - (或
store/blocks.json下的模板专属文件)通过引用块ID来定义每个页面模板的块树。块ID来自组件应用的store/blocks/,并由声明应用的主版本限定作用域。store/interfaces.json - 定义自定义店铺前端路由,并将其绑定到页面上下文(
store/routes.json、store.custom、store.product等)。原生路由(store.search、/、搜索路由)来自基础主题,几乎无需重新声明。/{slug}/p - 声明块的Site Editor可编辑属性。商家对这些属性的修改由
store/contentSchemas.json存储,存储键包含主题应用的主版本。vtex.pages-graphql - 店铺前端行为的修改有三个可选位置,请谨慎选择:
- 主题应用的目录下JSON文件——组合配置、路由、默认内容、允许的子块。发布后会立即影响所有购物者。
store/ - 组件应用代码——块的React行为。按照组件应用自身的版本节奏发布。
- Site Editor——在主题默认内容之上的商家管理内容覆盖。由存储,作用域限定为声明应用的已安装主版本。
vtex.pages-graphql
- 主题应用的
- 优先选择扩展基础主题而非复刻它。复刻基础主题会将所有块、路由和模板的维护责任永久转移到您的应用,包括上游的错误修复。
- 店铺前端页面是块的树形结构。叶子节点是组件块;分支节点是容器块(、
flex-layout.row等)。在设计允许的范围内,尽量保持树形结构扁平化;过深的树会增加渲染和内容的开销。flex-layout.col - 从的角度来看,主题应用是一个内容存储应用。其已安装的主版本是平台用于存储商家针对该应用声明的块所做的所有Site Editor修改的键的一部分。请将其版本协议视为面向商家,而非面向开发者。
vtex-io-storefront-theme-versioning
Hard constraints
硬性约束
Constraint: Theme apps must declare the store
builder and a base theme
store约束:主题应用必须声明store
构建器和基础主题
storeA storefront theme app MUST declare in and MUST depend on a base theme (typically ) unless it explicitly takes ownership of every native page template, block, and route.
"store"manifest.json#buildersvtex.store-themeWhy this matters
Without the builder, none of the files under are processed and the theme contributes nothing to the storefront. Without a base theme, the app is responsible for declaring every native page template (, , , etc.) from scratch — including upstream maintenance forever.
storestore/store.homestore.productstore.searchDetection
If a theme app ships or but its manifest does not declare in , STOP and add the builder. If the manifest also omits (or another base theme) from or without an explicit reason, STOP and confirm the app intends to own every native template.
store/blocks.jsonstore/routes.json"store"buildersvtex.store-themedependenciespeerDependenciesCorrect
json
{
"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"
}
}Wrong
json
{
"vendor": "acme",
"name": "store-theme",
"version": "1.0.0",
"builders": {
"messages": "1.x"
},
"dependencies": {}
}The files exist on disk but the platform ignores them, and the theme inherits nothing.
store/店铺前端主题应用必须在中声明,并且必须依赖一个基础主题(通常为),除非它明确承担所有原生页面模板、块和路由的所有权。
manifest.json#builders"store"vtex.store-theme重要性说明
如果没有构建器,目录下的所有文件都不会被处理,主题对店铺前端没有任何贡献。如果没有基础主题,应用需要从头开始声明所有原生页面模板(、、等)——包括永久承担上游维护工作。
storestore/store.homestore.productstore.search检测方式
如果主题应用包含或,但其未在中声明,请立即停止并添加该构建器。如果在或中也未包含(或其他基础主题)且无明确理由,请立即停止并确认该应用是否有意承担所有原生模板的所有权。
store/blocks.jsonstore/routes.jsonmanifestbuilders"store"manifestdependenciespeerDependenciesvtex.store-theme正确示例
json
{
"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"
}
}错误示例
json
{
"vendor": "acme",
"name": "store-theme",
"version": "1.0.0",
"builders": {
"messages": "1.x"
},
"dependencies": {}
}磁盘上存在文件,但平台会忽略它们,且主题不会继承任何内容。
store/Constraint: Block IDs in store/blocks.json
must resolve to a registered block in an installed app
store/blocks.json约束:store/blocks.json
中的块ID必须能解析为已安装应用中注册的块
store/blocks.jsonEvery block ID referenced in (or per-template files) MUST be declared in an of an installed app whose MAJOR version matches what the platform resolves at render time. Unresolved block IDs cause errors at the GraphQL layer and break the page.
store/blocks.jsoninterfaces.jsonMissing blockWhy this matters
vtex.pages-graphqlvendor.app@MAJOR.x:block-idDetection
If references a block ID, verify that some app in declares it in at the major version range listed in the dependency. If the dependency is , the block must exist in the line of that app, not the line.
store/blocks.jsonmanifest.json#dependenciesstore/interfaces.jsonacme.product-widgets@0.x0.x5.xCorrect
json
// manifest.json
{
"dependencies": {
"vtex.store-theme": "2.x",
"acme.product-widgets": "0.x"
}
}json
// store/blocks.json
{
"store.product": {
"children": [
"flex-layout.row#product-main",
"acme-related-products"
]
},
"acme-related-products": {
"props": { "limit": 8 }
}
}json
// acme.product-widgets@0.x ships store/interfaces.json with:
{
"acme-related-products": {
"component": "RelatedProducts"
}
}Wrong
json
// manifest.json depends on acme.product-widgets@0.x
// but store/blocks.json references a block that only exists in @5.x
{
"store.product": {
"children": ["acme-new-related-products"]
}
}The render-time resolver returns and the page fails.
Missing block acme.product-widgets@0.x:acme-new-related-productsstore/blocks.jsoninterfaces.jsonMissing block重要性说明
vtex.pages-graphqlvendor.app@MAJOR.x:block-id检测方式
如果引用了某个块ID,请验证中的某个应用是否在其依赖列表中指定的主版本范围内的中声明了该块。如果依赖是,则该块必须存在于该应用的版本系列中,而非版本系列。
store/blocks.jsonmanifest.json#dependenciesstore/interfaces.jsonacme.product-widgets@0.x0.x5.x正确示例
json
// manifest.json
{
"dependencies": {
"vtex.store-theme": "2.x",
"acme.product-widgets": "0.x"
}
}json
// store/blocks.json
{
"store.product": {
"children": [
"flex-layout.row#product-main",
"acme-related-products"
]
},
"acme-related-products": {
"props": { "limit": 8 }
}
}json
// acme.product-widgets@0.x 包含的 store/interfaces.json:
{
"acme-related-products": {
"component": "RelatedProducts"
}
}错误示例
json
// manifest.json 依赖 acme.product-widgets@0.x
// 但 store/blocks.json 引用了仅存在于 @5.x 版本中的块
{
"store.product": {
"children": ["acme-new-related-products"]
}
}渲染时解析器会返回,页面加载失败。
Missing block acme.product-widgets@0.x:acme-new-related-productsConstraint: Custom routes in store/routes.json
must bind to a real page context and template
store/routes.json约束:store/routes.json
中的自定义路由必须绑定到真实的页面上下文和模板
store/routes.jsonEvery entry in MUST set a valid , a (or rely on the built-in context for native page IDs such as ), and a template that exists in the block tree (the page ID itself, or a declared in ).
store/routes.jsonpathcontextstore.productstore.custom#<id>store/blocks.jsonWhy this matters
A route entry without a resolvable template renders nothing. A route entry with the wrong context (e.g., a custom institutional page typed as ) executes the wrong data resolver and crashes or returns empty product data.
store.productDetection
For each route in , confirm: (a) the does not collide with native VTEX paths, (b) the bound page ID exists as a key in , and (c) the matches the data the page actually needs.
store/routes.jsonpathstore/blocks.jsoncontextCorrect
json
// store/routes.json
{
"store.custom#about": {
"path": "/institucional/sobre",
"context": "vtex.store-resources/InstitutionalPageContext"
}
}json
// store/blocks.json
{
"store.custom#about": {
"blocks": ["rich-text#about-body"]
}
}Wrong
json
// store/routes.json
{
"store.custom#about": {
"path": "/p/sobre"
}
}Path collides with the native PDP route shape, no is declared, and there is no matching template in .
/p/sobrecontextstore.custom#aboutstore/blocks.jsonstore/routes.jsonpathcontextstore.productstore/blocks.jsonstore.custom#<id>重要性说明
没有可解析模板的路由条目无法渲染任何内容。上下文错误的路由条目(例如,将自定义企业页面标记为)会执行错误的数据解析器,导致崩溃或返回空的产品数据。
store.product检测方式
对于中的每个路由,请确认:(a) 不与VTEX原生路径冲突;(b) 绑定的页面ID在中存在对应的键;(c) 与页面实际需要的数据匹配。
store/routes.jsonpathstore/blocks.jsoncontext正确示例
json
// store/routes.json
{
"store.custom#about": {
"path": "/institucional/sobre",
"context": "vtex.store-resources/InstitutionalPageContext"
}
}json
// store/blocks.json
{
"store.custom#about": {
"blocks": ["rich-text#about-body"]
}
}错误示例
json
// store/routes.json
{
"store.custom#about": {
"path": "/p/sobre"
}
}路径与原生PDP路由格式冲突,未声明,且中没有匹配的模板。
/p/sobrecontextstore/blocks.jsonstore.custom#aboutPreferred pattern
推荐模式
Recommended theme app structure:
text
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.jsoncRecommended composition:
store.homejson
{
"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"
}
}
}Recommended custom institutional route:
json
// store/routes.json
{
"store.custom#about": {
"path": "/institucional/sobre",
"context": "vtex.store-resources/InstitutionalPageContext"
}
}json
// 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."
}
}
}Recommended Site Editor-editable surface:
json
// store/contentSchemas.json
{
"rich-text#about-copy": {
"type": "object",
"properties": {
"text": {
"type": "string",
"title": "Body copy",
"widget": { "ui:widget": "textarea" }
}
}
}
}Merchant edits to are persisted by under a key that includes the theme app's MAJOR version. See for what happens to that content on a major bump and how to migrate it with the mutation.
textvtex.pages-graphqlvtex-io-storefront-theme-versioningupdateThemeIds推荐的主题应用结构:
text
acme.store-theme/
├── manifest.json # store构建器、基础主题依赖
├── messages/ # 本地化字符串(对应单独技能)
└── store/
├── blocks.json # 全局块声明
├── routes.json # 自定义路由
├── contentSchemas.json # Site Editor可编辑属性
└── blocks/ # 按模板划分的块树
├── home.jsonc
├── product.jsonc
├── search.jsonc
├── category.jsonc
└── custom/
├── about.jsonc
└── stores.jsonc推荐的组合配置:
store.homejson
{
"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"
}
}
}推荐的自定义企业路由:
json
// store/routes.json
{
"store.custom#about": {
"path": "/institucional/sobre",
"context": "vtex.store-resources/InstitutionalPageContext"
}
}json
// 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可编辑界面配置:
json
// store/contentSchemas.json
{
"rich-text#about-copy": {
"type": "object",
"properties": {
"text": {
"type": "string",
"title": "Body copy",
"widget": { "ui:widget": "textarea" }
}
}
}
}商家对的修改会由存储在包含主题应用主版本的键下。关于主版本升级时这些内容的变化,以及如何使用 mutation进行迁移,请参考。
textvtex.pages-graphqlupdateThemeIdsvtex-io-storefront-theme-versioningCommon failure modes
常见失败模式
- Forking instead of depending on it, then losing every upstream block fix and route addition forever.
vtex.store-theme - Referencing a block ID in that exists in a different major of the declaring app than the dependency range allows.
store/blocks.json - Declaring the same block ID in two different apps and getting non-deterministic resolution at render time.
- Putting Site Editor-editable copy directly in
store/blocks.jsonwithoutprops, so merchants cannot change it.contentSchemas.json - Adding a custom route to without adding the matching
store/routes.jsontemplate instore.custom#<id>.store/blocks.json - Treating the theme app's version as developer-facing and bumping the major to "tidy up", which leaves the new major with no merchant content and forces an migration in
updateThemeIdsbefore promote (seevtex.pages-graphql@2.x).vtex-io-storefront-theme-versioning - Putting React component code in the theme app instead of in a dedicated component app, which mixes block declaration with block consumption and complicates reuse.
- Storing operational or shopper-specific data in theme files. The theme is global; per-shopper or per-segment data belongs elsewhere.
store/
- 复刻而非依赖它,导致永久丢失所有上游块修复和路由新增内容。
vtex.store-theme - 在中引用的块ID存在于声明应用的其他主版本中,而非依赖范围允许的版本。
store/blocks.json - 在两个不同应用中声明相同的块ID,导致渲染时解析结果不确定。
- 将Site Editor可编辑的文案直接硬编码在的
store/blocks.json中,未使用props,导致商家无法修改。contentSchemas.json - 在中添加自定义路由,但未在
store/routes.json中添加匹配的store/blocks.json模板。store.custom#<id> - 将主题应用的版本视为面向开发者,为了“整理”而升级主版本,导致新版本没有商家内容,必须在发布前使用中的
vtex.pages-graphql@2.x进行迁移(参考updateThemeIds)。vtex-io-storefront-theme-versioning - 将React组件代码放在主题应用中,而非专用的组件应用,导致块声明与块使用混合,增加复用难度。
- 将运营或购物者特定数据存储在主题的文件中。主题是全局的;针对特定购物者或细分群体的数据应存储在其他位置。
store/
Review checklist
审核清单
- Does declare the
manifest.jsonbuilder?store - Does the theme depend on a base theme, or is full ownership of native templates explicit and intentional?
- Does every block ID in resolve to a real
store/blocks.jsonentry in an installed app at a matching major?interfaces.json - Does every entry in have a valid
store/routes.json,path, and matching template incontext?store/blocks.json - Are merchant-editable copy and image fields exposed through rather than hardcoded in
contentSchemas.json?props - Are React components kept out of the theme app and in dedicated component apps?
- Has the team considered whether a planned change would force a major version bump on this content-holding app?
- 是否声明了
manifest.json构建器?store - 主题是否依赖基础主题,或者是否明确有意承担所有原生模板的所有权?
- 中的每个块ID是否能解析为已安装应用中对应主版本的
store/blocks.json条目?interfaces.json - 中的每个条目是否有有效的
store/routes.json、path,以及context中匹配的模板?store/blocks.json - 商家可编辑的文案和图片字段是否通过暴露,而非硬编码在
contentSchemas.json中?props - React组件是否被排除在主题应用之外,放在专用的组件应用中?
- 团队是否考虑过计划中的修改是否会强制这个内容存储应用升级主版本?
Related skills
相关技能
- — Use when the question is how to safely change which version of this theme app is installed on
vtex-io-storefront-theme-versioning.master - — Use when the question is how a block ID becomes a React component, or how a component app should declare blocks for themes to consume.
vtex-io-render-runtime-and-blocks - — Use when the question is the React implementation of a block, not its composition into pages.
vtex-io-storefront-react - — Use when the question is what the theme app's manifest contract should declare and how it interacts with base themes and component apps.
vtex-io-app-contract
- — 当您需要了解如何安全修改
vtex-io-storefront-theme-versioning环境中已安装的主题应用版本时使用。master - — 当您需要了解块ID如何转换为React组件,或组件应用应如何声明供主题使用的块时使用。
vtex-io-render-runtime-and-blocks - — 当您需要了解块的React实现而非其页面组合方式时使用。
vtex-io-storefront-react - — 当您需要了解主题应用的
vtex-io-app-contract协议应声明哪些内容,以及它如何与基础主题和组件应用交互时使用。manifest
Reference
参考资料
- Store Framework — How theme apps assemble pages from blocks and templates.
- Using Components — How to reference blocks from base themes and component apps.
- Themes — Theme app structure and the relationship to .
vtex.store-theme - Routes — Declaring custom storefront routes and binding them to page contexts.
- Making a Custom Component Available in Site Editor — and the Site Editor surface.
contentSchemas.json
- Store Framework — 主题应用如何通过块和模板组装页面。
- Using Components — 如何引用基础主题和组件应用中的块。
- Themes — 主题应用结构及其与的关系。
vtex.store-theme - Routes — 声明自定义店铺前端路由并将其绑定到页面上下文。
- Making a Custom Component Available in Site Editor — 与Site Editor操作界面。
contentSchemas.json