commercetools-storefront

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

commercetools Storefront (framework-agnostic)

commercetools Storefront(框架无关)

Production patterns for commercetools storefronts — covering the full range from the shared BFF foundation to B2C and B2B surface-specific features. The patterns here are framework-neutral: each is stated as a decision plus commercetools-exact code. Your frontend framework supplies the implementation primitives (file layout, render and routing primitives, the cookie read/write binding).
Architecture assumption — a server tier exists. These patterns assume your storefront runs on a stack with a server-side tier (SSR / server components / a standalone BFF service) that can hold secrets and proxy commercetools. The BFF and secret rules below are non-negotiable and depend on this. They are designed SSR-first. For a specific framework, use its stack adapter under
references/stack/
— e.g. the Next.js stack — which maps each concept here to that framework's primitives and owns all file-layout and render-primitive details.
Reference implementation. Where a code example shows a file path or a render primitive, it uses the Next.js App Router as the reference implementation. The framework-neutral rule is always in the surrounding prose; the adapter pins the exact primitive.
Path & state conventions.
Each reference implementation follows these conventions for paths and state management. The conventions are not technically required, but they are widely used in production storefronts and make it easier to navigate the codebase and onboard new developers. Find the
concept-mapping.md
in your stack adapter for the exact primitives used.
ConventionMeaning
<server>/
Your server-side code root; each stack pins the actual directory (Example Next.js:
lib/
)
<api>/
the client-facing API surface the browser calls and routes
<server>/ct/*
The commercetools helper modules
<server>/ct/client
The
apiRoot
singleton
<server>/types
The app type-mapping root (the boundary types)
<server>/mappers/
The commercetools→app mappers
Client stateYour framework's client-side state-management / cache layer (the specific library is a stack choice) — use it for mutable per-user data
用于 commercetools Storefront 的生产级模式——覆盖从共享 BFF 基础架构到 B2C 与 B2B 各业务界面专属功能的完整范围。此处的模式与框架无关:每项模式都由一项决策和可直接用于 commercetools 的精确代码组成。你的前端框架提供实现原语(文件布局、渲染与路由原语,以及 Cookie 读写绑定)。
架构假设——存在服务端层。 这些模式假定你的 Storefront 运行在具备服务端层(SSR / Server Components / 独立 BFF 服务)的技术栈上,该层可保存密钥并代理 commercetools。下方关于 BFF 和密钥的规则不可更改,并依赖此前提。它们以 SSR 优先。对于特定框架,请使用
references/stack/
下的技术栈适配器——例如 Next.js 技术栈——它会将这里的每个概念映射到该框架的原语,并负责所有文件布局和渲染原语细节。
参考实现。 当代码示例展示文件路径或渲染原语时,均以 Next.js App Router 作为参考实现。框架无关的规则始终以周边文字为准;适配器负责确定精确原语。
路径与状态约定。
每个参考实现都遵循以下路径和状态管理约定。这些约定并非技术必需,但广泛用于生产级 Storefront,有助于浏览代码库并帮助新开发者快速上手。技术栈适配器中的
concept-mapping.md
会给出所用原语的准确映射。
约定含义
<server>/
服务端代码根目录;具体技术栈会确定实际目录(Next.js 示例:
lib/
)
<api>/
浏览器调用和路由的客户端 API 接口层
<server>/ct/*
commercetools 辅助模块
<server>/ct/client
apiRoot
单例
<server>/types
应用类型映射根目录(边界类型)
<server>/mappers/
commercetools→应用的映射器
客户端状态框架的客户端状态管理/缓存层(具体库由技术栈决定)——用于存储每位用户的可变数据

Workflow

工作流

When this skill is invoked, always follow these steps:
  1. <!-- ct:docs-search:begin -->
    Docs search (required, run first) — The first time you use this skill in a session you must run this before answering. It gathers the latest verified documentation as your primary grounding, filtered to the products this skill covers. Use this script for documentation search while working with this skill; the Knowledge MCP covers everything else. Always confirm details against retrieved documentation rather than the skill text alone:
    bash
    node "<this skill's directory>/scripts/docs-search.mjs" \
      --query "<extract key terms from user's question>" \
      --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
      --model "<current-model>" \
      --commercetools-project-key "<if known>" \
      --commercetools-region "<if known>" \
      --limit 10
    Pass the commercetools project key and region (as in
    api.{region}.commercetools.com
    ) only if already in your context; otherwise omit both. Never search files or ask the user for them.
    <!-- ct:docs-search:end -->
  2. Combine with skill references — Cross-reference the analysis output with local references in
    ./references/
    for complete context.
  3. Provide implementation guidance — Synthesize the documentation with the specific integration mode the user is targeting.
调用此 skill 时,始终遵循以下步骤:
  1. <!-- ct:docs-search:begin -->
    文档搜索(必做,首先运行)——首次在会话中使用此 skill 时,必须在回答前运行此操作。它会检索最新且经过验证的文档,并按此 skill 覆盖的产品进行过滤,将其作为主要依据。处理此 skill 时,使用此脚本进行文档搜索;Knowledge MCP 负责其他所有内容。始终对照检索到的文档确认细节,而不要只依赖 skill 文本:
    bash
    node "<this skill's directory>/scripts/docs-search.mjs" \
      --query "<extract key terms from user's question>" \
      --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
      --model "<current-model>" \
      --commercetools-project-key "<if known>" \
      --commercetools-region "<if known>" \
      --limit 10
    仅当上下文中已包含 commercetools project key 和 region(格式为
    api.{region}.commercetools.com
    )时才传入;否则将两者省略。切勿搜索文件或向用户索要这些信息。
    <!-- ct:docs-search:end -->
  2. 结合 skill 参考资料——将分析结果与
    ./references/
    中的本地参考资料交叉核对,以获得完整上下文。
  3. 提供实现指导——综合文档与你面向的具体集成模式。

Optional scripts

可选脚本

Fetch GraphQL schema — Run this when you need context about a commercetools GraphQL query or mutation — for example, to inspect a resource's fields, types, and available operations before writing a query, or to verify a GraphQL query/mutation you have just generated against the real schema. It fetches the partial GraphQL SDL for a single commercetools resource:
bash
node scripts/graphql-schemata.mjs \
  --resource-name "<commercetools resource, e.g. Cart, Product, Order>" \
  --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
  --model "<current-model>"
The output is the GraphQL SDL for that resource. If the resource name is not recognized, the script prints the list of valid resource names — pick the correct one and re-run. Note: the SDL may contain stubbed types — referenced resources rendered as stubs, with their real type name given in a comment. Fetch any you need separately by re-running this script with that type name as
--resource-name
.
Fetch OpenAPI (REST) schema — Run this when you need context about a commercetools REST endpoint, request/response payload, or update action — for example, to inspect a resource's REST operations before constructing a request, or to verify a REST request/payload you have just generated against the real specification. It fetches the partial OpenAPI specification for a single commercetools resource:
bash
node scripts/openApi-schemata.mjs \
  --resource-name "<commercetools resource, e.g. api-Cart-write, api-Customer-read, checkout-Application>" \
  --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
  --model "<current-model>"
The output is the OpenAPI specification (YAML) for that resource. REST resources use a read/write-split naming form (e.g.
api-Cart-read
,
api-Cart-write
). If the resource name is not recognized, the script prints the list of valid resource names — pick the correct one and re-run. Note: the spec does not include reference-expansion schemas — fetch a referenced resource's schema separately by re-running this script with that resource as
--resource-name
.
获取 GraphQL schema——当需要了解 commercetools GraphQL 查询或 mutation 的上下文时运行此脚本——例如,在编写查询前检查资源的字段、类型和可用操作,或针对真实 schema 验证刚生成的 GraphQL 查询/mutation。它会获取单个 commercetools 资源的部分 GraphQL SDL:
bash
node scripts/graphql-schemata.mjs \
  --resource-name "<commercetools resource, e.g. Cart, Product, Order>" \
  --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
  --model "<current-model>"
输出为该资源的 GraphQL SDL。如果无法识别资源名称,脚本会打印有效资源名称列表——选择正确名称后重新运行。注意: SDL 可能包含存根类型——引用资源仅以存根形式呈现,并在注释中给出其真实类型名。请使用该类型名作为
--resource-name
重新运行脚本,分别获取所需资源。
获取 OpenAPI(REST)schema——当需要了解 commercetools REST endpoint、请求/响应 payload 或 update action 的上下文时运行此脚本——例如,在构建请求前检查资源的 REST 操作,或针对真实规范验证刚生成的 REST 请求/payload。它会获取单个 commercetools 资源的部分 OpenAPI 规范:
bash
node scripts/openApi-schemata.mjs \
  --resource-name "<commercetools resource, e.g. api-Cart-write, api-Customer-read, checkout-Application>" \
  --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
  --model "<current-model>"
输出为该资源的 OpenAPI 规范(YAML)。REST 资源使用读写分离的命名形式,例如
api-Cart-read
、
api-Cart-write
。如果无法识别资源名称,脚本会打印有效资源名称列表——选择正确名称后重新运行。注意: 该规范不包含引用展开 schema——请使用被引用资源作为
--resource-name
重新运行脚本,分别获取其 schema。

Key Takeaways

核心要点

The BFF pattern is non-negotiable. All commercetools API calls go through a server endpoint (BFF). The browser never calls commercetools directly. Secrets are never exposed to the client bundle (no public env prefix). (This requires a server tier — see the architecture assumption above.)
Sessions are server-managed. The BFF owns session state and is the only tier that reads or writes it. How it's stored is a stack choice — a signed token in an HTTP-only cookie (stateless BFF), or a server-side session store keyed by an opaque cookie (stateful BFF). Either way the client never holds session secrets or raw commercetools credentials — only an opaque reference. Any session-signing secret must be strong and is never hardcoded or exposed to the client.
Server-rendered loads for catalog data; client state for mutable user state. Catalog/immutable data (category pages, PDPs) is loaded on the server, calling
<server>/ct/*
directly. Cart, account, and user-specific data are loaded into client-side state management → server endpoint → commercetools SDK.
<server>/ct/*
is server-only.
Never import it from a client component. Import types from the app type-mapping root (
<server>/types
).

BFF 模式不可更改。 所有 commercetools API 调用都必须通过服务端 endpoint(BFF)完成。浏览器绝不直接调用 commercetools。密钥绝不暴露给客户端 bundle(不使用 public env 前缀)。(这需要服务端层——参见上文架构假设。)
会话由服务端管理。 BFF 拥有会话状态,并且是唯一读取或写入会话的层。如何存储由技术栈决定——可以是在 HTTP-only Cookie 中保存签名令牌(无状态 BFF),也可以是以不透明 Cookie 为键的服务端会话存储(有状态 BFF)。无论采用哪种方式,客户端都不持有会话密钥或原始 commercetools 凭据,只持有一个不透明引用。任何会话签名密钥都必须足够强,且不得硬编码或暴露给客户端。
目录数据使用服务端渲染加载;可变用户状态使用客户端状态。 目录/不可变数据(分类页面、PDP)在服务端加载,并直接调用
<server>/ct/*
。购物车、账户和用户特定数据则加载到客户端状态管理 → 服务端 endpoint → commercetools SDK。
<server>/ct/*
仅限服务端使用。
切勿从客户端组件导入它。请从应用类型映射根目录(
<server>/types
)导入类型。

Decision Steps

决策步骤

Build a storefront in this order — each step maps to a section of the Reference Index below:
  1. Choose your stack (if exists). Pick the adapter under
    references/stack/<name>/
    for your frontend. It owns file layout, render/routing primitives, the session mechanism, the client-state library, and deploy.
  2. Implement the shared foundation. Wire the BFF boundary, sessions, commercetools client, type boundary, cart, and data-loading —
    references/core/
    .
  3. Add optional core features. Layer in cross-cutting extras (e.g. recurring prices/orders) as needed —
    references/core/optional/
    .
  4. Choose B2C or B2B. Load the matching surface for its domain features and rules —
    references/b2c/
    or
    references/b2b/
    .
  5. Add optional surface features. Layer in surface-specific extras .

按以下顺序构建 Storefront——每一步都对应下方参考索引中的一节:
  1. 选择技术栈(如果存在)。 为你的前端选择
    references/stack/<name>/
    下的适配器。它负责文件布局、渲染/路由原语、会话机制、客户端状态库和部署。
  2. 实现共享基础架构。 接入 BFF 边界、会话、commercetools 客户端、类型边界、购物车和数据加载——
    references/core/
    。
  3. 添加可选的核心功能。 按需叠加跨领域附加功能,例如周期性价格/订单——
    references/core/optional/
    。
  4. 选择 B2C 或 B2B。 加载与业务领域功能和规则匹配的界面——
    references/b2c/
    或
    references/b2b/
    。
  5. 添加可选的界面专属功能。 按需叠加界面专属附加功能。

Reference Index

参考索引

Stacks

技术栈

Pick the adapter for your frontend stack. Each stack folder under
references/stack/<name>/
maps the framework-neutral patterns in this skill onto that stack's primitives and owns its file layout, render primitives, and deploy.
StackReferenceCommands
Next.js 16 (App Router) + next-intl v4 + Tailwind v4stack/nextjs/overview.md
/nextjs-setup-project
,
/nextjs-deploy-vercel
,
/nextjs-deploy-netlify
Nuxt 4 (Vue, SSR) + Nitro + @nuxtjs/i18n v10 + nuxt-auth-utils + Pinia + Tailwind v4stack/nuxtjs/overview.md
/nuxtjs-setup-project
为你的前端技术栈选择适配器。每个
references/stack/<name>/
下的技术栈目录会将此 skill 中与框架无关的模式映射到该技术栈的原语,并负责其文件布局、渲染原语和部署。
技术栈参考命令
Next.js 16(App Router)+ next-intl v4 + Tailwind v4stack/nextjs/overview.md
/nextjs-setup-project
、
/nextjs-deploy-vercel
、
/nextjs-deploy-netlify
Nuxt 4(Vue、SSR)+ Nitro + @nuxtjs/i18n v10 + nuxt-auth-utils + Pinia + Tailwind v4stack/nuxts/overview.md
/nuxtjs-setup-project

Shared Foundation (
references/core/
)

共享基础架构(
references/core/
)

TaskReference
Scaffold a new project (deps, styling, locale routing, folder structure)Framework-specific - see the adapter's
overview.md
commercetools SDK singleton, server-managed sessions, BFF boundarycore/ct-client.md
Shared auth patterns: commercetools login endpoint, server endpoint structure, client state hook, logoutcore/customer-auth.md
Add a new country / currency / locale —
COUNTRY_CONFIG
flat structure
core/add-country.md
Parallel fetching, server-side TTL caching, client-cache hydration, N+1 avoidancecore/performance.md
Product image URL transforms (CDN, Imgix, Cloudinary)core/image-config.md
Cart CRUD, cart state/context, client state hook, mini-cart drawercore/cart.md
Full-text search, facet config, URL state, rendererscore/search-facets.md
Add a new BFF endpoint + client state hook (the 3-layer pattern)core/add-api.md
Add a new standalone or CMS-driven pagecore/add-page.md
Server-rendered vs client-fetched decisions, mappers, BFF shape, 409 retrycore/data-loading.md
Checkout page flow, step routing, order placementcore/checkout-page.md
PDP route, variant selectors, shared product detail patternscore/product-detail.md
Shopping lists (wishlist, saved items)core/shopping-lists.md
任务参考
搭建新项目(依赖项、样式、Locale 路由、目录结构)框架相关——请参阅适配器的
overview.md
commercetools SDK 单例、由服务端管理的会话、BFF 边界core/ct-client.md
共享认证模式:commercetools 登录 endpoint、服务端 endpoint 结构、客户端状态 hook、登出core/customer-auth.md
添加新的国家/货币/Locale——
COUNTRY_CONFIG
扁平结构
core/add-country.md
并行获取、服务端 TTL 缓存、客户端缓存水合、避免 N+1core/performance.md
产品图片 URL 转换(CDN、Imgix、Cloudinary)core/image-config.md
购物车 CRUD、购物车状态/context、客户端状态 hook、迷你购物车抽屉core/cart.md
全文搜索、分面配置、URL 状态、渲染器core/search-facets.md
添加新的 BFF endpoint + 客户端状态 hook(三层模式)core/add-api.md
添加新的独立页面或 CMS 驱动页面core/add-page.md
服务端渲染与客户端获取的决策、映射器、BFF 结构、409 重试core/data-loading.md
结账页面流程、步骤路由、下单core/checkout-page.md
PDP 路由、变体选择器、共享产品详情模式core/product-detail.md
购物清单(收藏夹、已保存商品)core/shopping-lists.md

Core Optional Features (
references/core/optional/
)

核心可选功能(
references/core/optional/
)

TaskReference
Recurring prices — mapper, PDP gate, selector component, add-to-cart with recurrenceInfocore/recurring-prices.md
Recurring orders — scoping, state transitions, post-checkout creation, recurrence policiescore/recurring-orders.md
Deploy to VercelRun
/deploy-vercel
— checks commercetools credentials, then hands off to Vercel's official agent skill
Deploy to NetlifyRun
/deploy-netlify
— checks commercetools credentials, then hands off to Netlify's official agent skill
任务参考
周期性价格——映射器、PDP 开关、选择器组件、使用 recurrenceInfo 的加入购物车core/recurring-prices.md
周期性订单——作用域、状态转换、结账后创建、周期策略core/recurring-orders.md
部署到 Vercel运行
/deploy-vercel
——检查 commercetools 凭据,然后移交给 Vercel 官方 Agent skill
部署到 Netlify运行
/deploy-netlify
——检查 commercetools 凭据,然后移交给 Netlify 官方 Agent skill

B2C Storefront (
references/b2c/
)

B2C Storefront(
references/b2c/
)

TaskReference
B2C overview, key takeaways, full reference indexb2c/overview.md
Category pages, product mapper, commercetools Search API, ProductCard/Gridb2c/product-listing.md
B2C PDP route, image gallery, variant selectors, AddToCartButtonb2c/product-detail.md
Register, login, anonymous cart merge, protected account layoutb2c/customer-auth.md
Multi-step checkout, shipping methods, order placementb2c/checkout.md
Navigation patterns, header, mobile menub2c/navigation.md
Shared UI component libraryb2c/ui-components.md
PDP variant selector configuration (blocklist, swatch, sort)b2c/variant-config.md
Wishlist functionalityb2c/wishlist.md
任务参考
B2C 概览、核心要点、完整参考索引b2c/overview.md
分类页面、产品映射器、commercetools Search API、ProductCard/Gridb2c/product-listing.md
B2C PDP 路由、图片库、变体选择器、AddToCartButtonb2c/product-detail.md
注册、登录、匿名购物车合并、受保护的账户布局b2c/customer-auth.md
多步骤结账、配送方式、下单b2c/checkout.md
导航模式、页眉、移动端菜单b2c/navigation.md
共享 UI 组件库b2c/ui-components.md
PDP 变体选择器配置(阻止列表、色板、排序)b2c/variant-config.md
收藏夹功能b2c/wishlists.md

B2C Optional Features (
references/b2c/optional/
)

B2C 可选功能(
references/b2c/optional/
)

TaskReference
CSR impersonation, dual session, line-item price overrideb2c/optional/superuser.md
Buy Online Pick Up In Store — channel API, per-store inventoryb2c/optional/bopis.md
Product bundles — parent/child cart items, cascade updatesb2c/optional/bundles.md
Product discounts, cart discounts, discount codes, promotion bannersb2c/optional/promotions.md
Recurring prices — recurrencePrices[] array, gateb2c/recurring-prices.md
Recurring orders — customer scoping, originOrder expand, post-checkout create, skip/setScheduleb2c/recurring-orders.md
任务参考
CSR 身份模拟、双会话、行项目价格覆盖b2c/optional/superuser.md
Buy Online Pick Up In Store——渠道 API、各门店库存b2c/optional/bopis.md
产品套装——父/子购物车项目、级联更新b2c/optional/bundles.md
产品折扣、购物车折扣、折扣码、促销横幅b2c/optional/promotions.md
周期性价格——recurrencePrices[] 数组、开关b2c/recurring-prices.md
周期性订单——客户作用域、originOrder 展开、结账后创建、skip/setScheduleb2c/recurring-orders.md

B2B Storefront (
references/b2b/
)

B2B Storefront(
references/b2b/
)

TaskReference
B2B overview, key takeaways, full reference indexb2b/overview.md
Session fields, BU/store selection, channel data, BusinessUnitContextb2b/session-and-bu.md
ProductApi session scoping — store, channels, price injection, availabilityb2b/product-listing.md
B2B PDP route, variant selectors, session-scoped pricingb2b/product-detail.md
as-associate cart CRUD, CartContext, auto-creation with BU+storeb2b/cart.md
Cart checkout and "Request a Quote" submission, BU addresses, order placementb2b/checkout.md
Login endpoint, BU auto-select, session fields written at loginb2b/customer-auth.md
RBAC — all permission strings, usePermissions, UI gating patternsb2b/permissions.md
Quotes dashboard — CT data model, unified thread list per BU, status labels, client state hooksb2b/quotes.md
Quote buyer actions — accept & place order, decline, renegotiate, state guardsb2b/quote-actions.md
Approval rules, approval flows, predicate builder, tier modelb2b/approval-workflows.md
Dashboard shell, stat widgets, pages, sidebar nav itemsb2b/dashboard.md
Purchase lists (commercetools ShoppingList via as-associate, BU-scoped)b2b/purchase-lists.md
Add a new B2B BFF endpoint + client state hookb2b/add-api.md
B2B data loading — server-rendered vs client-fetched, mappers, BFF shapeb2b/data-loading.md
B2B variant selector configurationb2b/variant-config.md
任务参考
B2B 概览、核心要点、完整参考索引b2b/overview.md
会话字段、BU/门店选择、渠道数据、BusinessUnitContextb2b/session-and-bu.md
ProductApi 会话作用域——门店、渠道、价格注入、可用性b2b/product-listing.md
B2B PDP 路由、变体选择器、会话范围定价b2b/product-detail.md
as-associate 购物车 CRUD、CartContext、使用 BU+store 自动创建b2b/cart.md
购物车结账与“Request a Quote”提交、BU 地址、下单b2b/checkout.md
登录 endpoint、BU 自动选择、登录时写入的会话字段b2b/customer-auth.md
RBAC——所有权限字符串、usePermissions、UI 门控模式b2b/permissions.md
报价面板——CT 数据模型、每个 BU 的统一会话列表、状态标签、客户端状态 hooksb2b/quotes.md
报价买方操作——接受并下单、拒绝、重新议价、状态守卫b2b/quote-actions.md
审批规则、审批流程、谓词构建器、层级模型b2b/approval-workflows.md
面板外壳、统计组件、页面、侧边栏导航项b2b/dashboard.md
采购清单(通过 as-associate 使用 commercetools ShoppingList,限定 BU 作用域)b2b/shopping-lists.md
添加新的 B2B BFF endpoint + 客户端状态 hookb2b/add-api.md
B2B 数据加载——服务端渲染与客户端获取的决策、映射器、BFF 结构b2b/data-loading.md
B2B 变体选择器配置b2b/variant-config.md

B2B Optional Features (
references/b2b/optional/
)

B2B 可选功能(
references/b2b/optional/
)

TaskReference
Superuser role — view all store carts, switch cartsb2b/superuser.md
Recurring prices — recurrencePrices[] array, as-associate add-to-cart, PDP gateb2b/recurring-prices.md
Recurring orders — BU scoping, cart expand, create-from-cart, duplicate, dashboardb2b/recurring-orders.md

任务参考
Superuser 角色——查看所有门店购物车、切换购物车b2b/superuser.md
周期性价格——recurrencePrices[] 数组、as-associate 加入购物车、PDP 开关b2b/recurring-prices.md
周期性订单——BU 作用域、购物车展开、从购物车创建、复制、面板b2b/recurring-orders.md

Priority Tiers

优先级层级

CRITICAL

CRITICAL(关键)

  • BFF architecture —
    <server>/ct/*
    is server-only. Zero commercetools SDK imports in any client component. (Requires a server tier — see the architecture assumption.)
  • Session & client secrets — the commercetools client secret and any session-signing secret are server-only env vars, never hardcoded and never exposed to the client bundle (no public env prefix).
  • commercetools login endpoint —
    apiRoot.login().post()
    , never
    apiRoot.customers().login()
    .
  • B2B: as-associate chain — ALL B2B writes (cart, order, quote, approval, BU) go through
    apiRoot.asAssociate().*
    . Never use project-level
    apiRoot.*
    for user-facing B2B mutations.
  • B2B: session B2B fields —
    businessUnitKey
    +
    storeKey
    +
    distributionChannelId
    +
    supplyChannelId
    +
    productSelectionId
    are always written together from
    getStoreChannelData(storeKey)
    .
  • B2B: three-field locale atomicity —
    locale
    ,
    currency
    ,
    country
    must all be updated together. Reset
    cartId
    on locale/currency change.
Framework-version gates, find
overview.md
of your stack.
  • BFF 架构——
    <server>/ct/*
    仅限服务端使用。任何客户端组件中都不得导入 commercetools SDK。(需要服务端层——参见架构假设。)
  • 会话与客户端密钥——commercetools client secret 和任何会话签名密钥都必须是仅服务端环境变量,绝不能硬编码或暴露给客户端 bundle(不使用 public env 前缀)。
  • commercetools 登录 endpoint——
    apiRoot.login().post()
    ,切勿使用
    apiRoot.customers().login()
    。
  • B2B:as-associate 链——所有 B2B 写入(购物车、订单、报价、审批、BU)都通过
    apiRoot.asAssociate().*
    完成。面向用户的 B2B mutation 切勿使用 project-level
    apiRoot.*
    。
  • B2B:会话 B2B 字段——
    businessUnitKey
    +
    storeKey
    +
    distributionChannelId
    +
    supplyChannelId
    +
    productSelectionId
    始终一起从
    getStoreChannelData(storeKey)
    写入。
  • B2B:Locale 三字段原子性——
    locale
    、
    currency
    、
    country
    必须同时更新。Locale/货币变化时重置
    cartId
    。
技术栈版本门槛:查阅对应技术栈的
overview.md
。

HIGH

HIGH(高)

  • Parallel fetching —
    Promise.all
    for independent fetches in server-rendered loads. No request waterfalls.
  • Type safety — Frontend components import types from the app type-mapping root (
    <server>/types
    ), never from
    <server>/ct/*
    .
  • commercetools type boundary — Map commercetools SDK responses to app types in
    <server>/mappers/
    before they leave
    <server>/ct/
    .
  • Client state invalidation — invalidate/refresh the relevant client state after login, logout, and order placement.
  • B2B: BU key in client state-manager/cache keys — all dashboard state is keyed by
    businessUnitKey
    (e.g. a
    [KEY, businessUnitKey]
    tuple) so it refreshes on BU switch.
  • 并行获取——在服务端渲染加载中,对相互独立的请求使用
    Promise.all
    。禁止请求瀑布流。
  • 类型安全——前端组件从应用类型映射根目录(
    <server>/types
    )导入类型,切勿从
    <server>/ct/*
    导入。
  • commercetools 类型边界——在 commercetools SDK 响应离开
    <server>/ct/
    之前,将其映射为
    <server>/mappers/
    中的应用类型。
  • 客户端状态失效——登录、登出和下单后,使相关客户端状态失效/刷新。
  • B2B:客户端状态管理器/缓存键中的 BU key——所有面板状态均以
    businessUnitKey
    为键(例如
    [KEY, businessUnitKey]
    元组),以便切换 BU 时刷新。

MEDIUM

MEDIUM(中)

  • Product Search API — Use
    apiRoot.products().search()
    , never the deprecated
    productProjections().search()
    . See the
    commercetools-platform
    skill → product-search.md.
  • Server-side TTL cache — Wrap rarely-changing commercetools data in the framework's server-side cache-with-TTL. Never use it for per-user or per-session data. (Next.js:
    unstable_cache
    — see the adapter.)

  • Product Search API——使用
    apiRoot.products().search()
    ,切勿使用已弃用的
    productProjections().search()
    。请参阅
    commercetools-platform
    skill → product-search.md。
  • 服务端 TTL 缓存——使用框架的服务端 cache-with-TTL 包装很少变化的 commercetools 数据。切勿将其用于每位用户或每个会话的数据。(Next.js:
    unstable_cache
    ——请参阅适配器。)

Anti-Patterns Quick Reference

反模式快速参考

Anti-patternCorrect approach
Importing
<server>/ct/client
(
apiRoot
) in a client component
Use a client state hook → server endpoint →
<server>/ct/
Calling the endpoint (
fetch('/<api>/*')
) directly in a component
Encapsulate it in a client data/state module
new ClientBuilder()
inside a page or server endpoint
Singleton
apiRoot
in
<server>/ct/client
Raw
fetch()
to commercetools REST endpoints
Always use
apiRoot
— the SDK manages OAuth tokens and refresh
Exposing a commercetools secret to the client bundle (public env prefix)Server-only env var, no public prefix
product.name['en-US']
(hardcoded locale key)
getLocalizedString(product.name, locale)
(centAmount / 100).toFixed(2)
formatMoney(centAmount, currencyCode, locale)
Sequential
await
for independent fetches
Promise.all([fetchA(), fetchB()])
apiRoot.customers().login()
apiRoot.login().post()
commercetools SDK types in componentsTypes from
<server>/types
; mapped in
<server>/mappers/
B2B:
apiRoot.carts().post(...)
for a logged-in user
asAssociate().withAssociateIdValue(...).inBusinessUnitKey(...).carts().post(...)
B2B: BU-scoped client state not keyed by BUKey the state entry by
businessUnitKey
(e.g.
[KEY_ORDERS, businessUnitKey]
)
B2B:
StagedQuote.sellerComment
for per-round display
Quote.sellerComment
— the snapshot at quote creation time
B2B:
apiRoot.shoppingLists()
for purchase lists
asAssociate().*.shoppingLists()
— BU-scoped, permission-enforced
反模式正确做法
在客户端组件中导入
<server>/ct/client
(
apiRoot
)
使用客户端状态 hook → 服务端 endpoint →
<server>/ct/
在组件中直接调用 endpoint(
fetch('/<api>/*')
)
将其封装在客户端数据/状态模块中
在页面或服务端 endpoint 中使用
new ClientBuilder()
在
<server>/ct/client
中使用
apiRoot
单例
使用原始
fetch()
调用 commercetools REST endpoint
始终使用
apiRoot
——由 SDK 管理 OAuth token 和刷新
将 commercetools 密钥暴露给客户端 bundle(public env 前缀)使用仅服务端环境变量,不使用 public 前缀
product.name['en-US']
(硬编码 Locale key)
getLocalizedString(product.name, locale)
(centAmount / 100).toFixed(2)
formatMoney(centAmount, currencyCode, locale)
对相互独立的请求顺序执行
await
Promise.all([fetchA(), fetchB()])
apiRoot.customers().login()
apiRoot.login().post()
在组件中使用 commercetools SDK 类型使用
<server>/types
中的类型;在
<server>/mappers/
中完成映射
B2B:对已登录用户使用
apiRoot.carts().post(...)
asAssociate().withAssociateIdValue(...).inBusinessUnitKey(...).carts().post(...)
B2B:客户端状态未按 BU 限定作用域使用
businessUnitKey
作为状态项的键(例如
[KEY_ORDERS, businessUnitKey]
)
B2B:使用
StagedQuote.sellerComment
展示每轮内容
使用
Quote.sellerComment
——即创建报价时的快照
B2B:使用
apiRoot.shoppingLists()
获取采购清单
使用
asAssociate().*.shoppingLists()
——限定 BU 作用域并执行权限检查