ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Builder.io Salesforce Headless 插件实战:将 SFCC 商品与目录无缝接入可视化内容编辑

2026/9/16 15:32:15 拓冰建站 浏览量
Builder.io Salesforce Headless 插件实战:将 SFCC 商品与目录无缝接入可视化内容编辑 Builder.io Salesforce Headless 插件实战将 SFCC 商品与目录无缝接入可视化内容编辑【免费下载链接】builderVisual Development for React, Vue, Svelte, Qwik, and more项目地址: https://gitcode.com/GitHub_Trending/bu/builder导读Salesforce Commerce CloudSFCC旧称 Demandware的用户常常面临一个痛点商品与目录数据存放在商务后端而营销团队希望在 Builder.io 的可视化编辑器中直接引用这些商品实现选品即内容。本篇文章基于当前仓库中的builder.io/plugin-sfcc-headless插件源码位于 plugins/sfcc-headless完整讲解该插件的安装配置、六种字段类型、自定义定向Custom Targeting与自定义组件输入Custom Component Inputs的用法并结合源码剖析其代理请求、结果缓存与数据提供器的工作原理。读完本文你将能够在 Builder.io 中打通 SFCC 商品/目录数据并掌握本地开发、调试与发布该插件的一整套流程。插件概述一次配置两种资源三种使用场景该插件解决的核心问题是让 Builder.io 内容直接感知你的 Salesforce 商品Product与集合/目录Collection/Category。安装并配置好插件后Builder.io 会新增六个新的字段类型分别作用于模型Model字段、Symbol 输入与自定义组件字段三种场景同时提供可用的自定义定向属性Custom Targeting Attributes。从源码看这些能力的根基是registerCommercePlugin见 plugins/sfcc-headless/src/plugin.tsx插件以Salesforce为名称注册向 Builder.io 暴露一个实现了CommerceAPIOperations接口的服务对象其中包含product与category两类资源操作随后又通过appState.registerDataPlugin注册了数据提供器见 plugins/sfcc-headless/src/data-provider.ts将Product、Category以及ProductQueryproduct_search三种资源类型暴露给编辑器并自动生成SalesforceProduct、SalesforceCategory等字段类型输入。安装与连接配置在 Builder.io 中安装插件打开 Builder.io 的Space 设置页面builder.io/account/space在插件Plugins选项中输入插件包名builder.io/plugin-sfcc-headless保存后Builder.io 会提示你填写连接 SFCC 实例所需的配置项下方参数表依据 plugins/sfcc-headless/src/plugin.tsx 的settings定义整理。连接参数详解参数名显示名类型必填默认值说明与示例baseAPIbaseAPIURL是无SFCC 实例的基础地址例如https://development-test-name.demandware.netstorestoretext是无商店或库标识符例如STORE_NAME_USclientIdAPI Client IDtext是无SFCC OCAPI 的 API 客户端标识例如c418989-12312-49d1-...countryCodecountryCodetext否US默认国家代码例如USversionOCAPI Versiontext否v20_4OCAPI 版本默认v20_4localelocaletext否en-US默认语言环境例如en-US这些参数在运行时会被读取并拼装出访问 SFCC Shop API 的基础 URLconst baseAPI settings.get(baseAPI)?.trim(); const countryCode settings.get(countryCode)?.trim() || US; const locale settings.get(locale)?.trim() || en-US; const store settings.get(store)?.trim(); const clientId settings.get(clientId)?.trim(); const version settings.get(version)?.trim() || v20_4; const baseURL ${baseAPI}/s/${store}/dw/shop/${version};见 plugins/sfcc-headless/src/plugin.tsx可以看到最终请求路径遵循 SFCC OCAPI Shop 路由规范/s/{store}/dw/shop/{version}例如https://development-test-name.demandware.net/s/STORE_NAME_US/dw/shop/v20_4。自定义定向Custom Targeting按商品与目录做内容投放自定义定向让内容创作者能够根据宿主站点上报的属性attribute决定展示哪份内容。本插件提供两类定向字段Salesforce Product作为自定义定向类型使用时定向到字段值等于某个商品 ID的上下文。你需要在宿主环境中设置商品 ID设置方法见下文即可为指定商品投放专属内容。Salesforce Collection作为自定义定向属性使用时通过分类 ID 定向到指定目录/分类同样需要在宿主环境中设置分类 ID。说明README 中提到的按handle别名定向的字段类型名称沿用了 commercetools 插件的表述本仓库实际注册的字段类型名称以>builder.setUserAttributes({ product: currentProduct.id, });方式二在请求 Content API 时以 query param 形式传递userAttributes或在使用 Gatsby、Next.js 等框架调用 GraphQL API 时在查询参数中携带 targeting 信息。设置完成后当宿主环境上报的product属性与内容上配置的Salesforce Product定向值匹配时该内容即命中投放。自定义组件输入字段值自动解析为 Request 对象将Salesforce Product与Salesforce Collection用作模型字段、Symbol 输入或自定义组件字段时编辑器 UI 会弹出资源选择器Picker引导你搜索并选定商品/目录。选定后字段值不会直接存一个裸 ID而是被自动解析成 Builder.io 标准的Request对象{ yourFieldName: { type: builder.io/core:Request, request: { url: ... }, data: { // API 请求的响应数据例如 product: { /* ... */ } } } }这样做的价值在于无论是 Builder.io 的 API、各前端 SDK还是在 Builder.io 编辑器中字段值都能按需发起到 SFCC 的请求并拿到结构化的商品/目录数据而不必在客户端各自维护一份ID → 数据的映射。源码级的实现印证Request对象由getRequestObject生成见 plugins/sfcc-headless/src/plugin.tsx 与 plugin.tsx。商品与分类分别生成指向 SFCC OCAPI 的请求 URLgetRequestObject(id: string) { return { type: builder.io/core:Request as const, request: { url: proxyURL( ${baseURL}/products/${id}?displaystandardlocale${locale}country-code${countryCode} ), }, options: { product: id, }, }; }其中的proxyURL把真实请求包装为 Builder.io 的代理 API见 plugin.tsx从而避免在浏览器端暴露 SFCC 的clientId并将请求统一收敛到 Builder.io 网关const proxyURL (url: string) { const proxied new URL(url); proxied.searchParams.set(client_id, clientId); return ${appState.config.apiRoot()}/api/v1/proxy-api?debugtrueapiKey${ appState.user.apiKey }url${encodeURIComponent(proxied.toString())}; };源码剖析数据查询、结果缓存与资源转换商品查询product.search商品搜索调用 SFCC 的product_search端点并带有可选的分类、关键词、分页与refine约束见 plugin.tsxasync search(search: string, offset, limit) { const [category, q] (search || ).split(:); const key search:product:${search}:${offset}:${limit}; const response basicCache.get(key) || (await proxyFetch( ${baseURL}/product_search?count${limit || 60}start${ offset || 0 }refinec_allowedCountriesALL|USrefine_1c_displayOnstandard_usdrefine_2cgid${ category || all }country-code${countryCode}locale${locale}${q ? q${q} : } ).then(res res.json())); basicCache.set(key, response); return (response.hits || []) .map((hit: any) ({ id: hit.product_id, name: hit.product_name, })) .map(transformResource); }要点解读搜索串以:分隔分类:关键词这是插件内部约定的解析协议默认每页 60 条、refine限定可售国家与展示渠道cgid指定目录分组默认all查询结果与商品详情都写入basicCache一个Map避免同一会话内重复请求。分类查询category.search分类支持按 ID 精确获取与按名称搜索/categories/(search)语法响应兼容response.categories与response.data[0].categories两种结构见 plugin.tsx。资源标准化transformResource所有商品与分类在返回给编辑器前都会被统一转换为标准资源结构见 plugin.tsx以id为键、拼接出[id] name形式的标题、提取slug作为handle若存在自定义图片字段c_imageURL则一并映射为缩略图。这正是 Picker 界面中列表项渲染ResourcePreviewCell所依赖的数据契约。数据提供器与 ProductQueryregisterDataPlugin注册的资源类型除了Product、Category对应字段类型SalesforceProduct、SalesforceCategory之外还有一个ProductQueryproduct_search类型见>git clone https://github.com/BuilderIO/builder.git cd plugins/sfcc-headless npm install仓库即根目录插件源码位于 plugins/sfcc-headless可直接进入该目录执行安装。当前仓库只读请在自己的克隆副本中操作。启动开发服务器npm startnpm start实际执行SERVEtrue rollup -c rollup.config.ts -w见 plugins/sfcc-headless/package.json即用 Rollup 以监听模式构建插件并通过rollup-plugin-serve在http://localhost:1268提供服务见 plugins/sfcc-headless/rollup.config.ts。构建产物为dist/plugin.system.jsSystemJS 格式并开启了Access-Control-Allow-Origin: *与Access-Control-Allow-Private-Network头以支持本地调试。将本地插件接入 Builder.io打开 Builder.io 的组织Organization设置页builder.io/account/organization在插件设置中将本地开发地址添加为插件http://localhost:1268/plugin.system.js?pluginIdbuilder.io/plugin-sfcc-headless注插件 ID 应与 package.json 中的包名builder.io/plugin-sfcc-headless保持一致源码注释也强调 should always match package.json package name见 plugin.tsx。README 中出现的builder.io/ecom-commercetools-is系从 commercetools 插件复制残留请以包名为准。注意 HTTPS 混用警告在 https 的 Builder.io 站点上加载http://localhost内容会触发浏览器的安全提示。需要点击浏览器右上角的盾牌图标选择load unsafe scripts加载不安全的脚本以允许本地 http 内容在 Builder 的 https 站点上运行。此后每次修改源码Rollup 的 watch 模式会自动重新构建重新刷新 Builder.io 页面即可看到插件的最新版本。卸载插件在 Builder.io 的插件 UI 中移除该插件条目即可无需其他清理操作。验证插件效果创建一个自定义模型、组件或 Symbol为它添加一个 Salesforce 字段如SalesforceProduct即可在编辑器中搜索 SFCC 商品并完成绑定——这正是插件开箱即用的核心体验。界面交互实现商品选择器与分类树仓库中的两个 Picker 组件让在编辑器里选商品/选目录成为可能ProductsPicker.tsx提供按分类、按关键词、按商品 ID三种筛选方式筛选面板基于renderEditor动态渲染SalesforceCategory等字段列表使用react-infinite-scroll-component实现无限滚动每页 30 条并通过throttle控制搜索与加载频率还会把最近选择的根分类写入localStoragekey 为sfcc-headless.lastChoice下次打开自动恢复。CategoriesPicker.tsx以可展开的树形面板浏览分类层级展开某个分类后递归渲染子分类支持输入分类 ID/名称后通过goUp回溯到父级分类依据响应中的parent_category_id。这两个组件都基于builder.io/commerce-plugin-tools提供的ResourcePickerProps、ResourcePreviewCell等基础设施构建与插件主服务无缝协作。技术栈与构建约定插件 UI 采用React Material UI构建样式使用EmotionCSS-in-JS状态管理使用MobX / mobx-react——这也是 Builder.io 官方推荐的插件技术栈能保证插件在编辑器中拥有最佳的表现与性能。构建层面见 rollup.config.ts有一个关键约定react、builder.io/react、builder.io/app-context、material-ui/core、emotion/*、mobx等必须声明为external与 Builder.io 主应用共享同一份依赖实例否则插件无法正常挂载运行。日常开发中常用命令npm run build # 执行 rollup -c rollup.config.ts 产出 dist/plugin.system.js npm run lint # tslint 校验 src 与 test npm start # 监听模式 本地 1268 端口服务本地调试小结builder.io/plugin-sfcc-headless以两种资源、三类使用场景、六种字段类型为骨架把 SFCC 的商品与目录能力完整地接入 Builder.io 的内容生态既能用于内容定向Custom Targeting也能作为模型/组件/Symbol 的动态数据字段自动解析为Request对象。源码层面插件通过 OCAPI Shop 端点 Builder.io 代理 API 统一数据通路配合会话级缓存与标准化资源转换兼顾了安全性、性能与编辑体验。若你需要为其他商务平台如 commercetools、Shopify 等做类似的接入本插件的 plugin.tsx 与 contenteditable="false">【免费下载链接】builderVisual Development for React, Vue, Svelte, Qwik, and more项目地址: https://gitcode.com/GitHub_Trending/bu/builder创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考