店面概览
店面位于 rCommerce 仓库的 storefront/ 目录,是一个带 React islands
的 Astro 站点。它的设计目标是一套代码服务多家店铺:每家店铺是
一个独立的 Cloudflare Pages 项目,所有店铺差异都通过 PUBLIC_*
环境变量在构建时注入。
生产实例:同一套代码同时服务 store-a.example.com(my-storefront
项目)和 store-b.example.com(store-b-pages 项目)。
构建时品牌配置
Section titled “构建时品牌配置”品牌身份在构建时由 src/lib/brand/config.ts 解析,并由 Astro 内联
——不存在运行时切换。
| 变量 | 作用 | 默认值 |
|---|---|---|
PUBLIC_BRAND_SLUG | 店铺标识(store-a、store-b)——选择对应品牌的页面变体 | store-a |
PUBLIC_BRAND_NAME | 页头、页脚、邮件中显示的店铺名称 | My Shop |
PUBLIC_BRAND_LOGO | public/ 下的 logo 路径 | /images/store-a-logo.png |
PUBLIC_BRAND_PRIMARY | 主题色(Tailwind primary) | #2563EB |
PUBLIC_BRAND_MENU | 页头/页脚分类,逗号分隔的 slug:Label 对 | gear/apparel/accessories |
PUBLIC_HERO_VIDEO_URL | 首页 hero 视频的 Cloudflare Stream iframe 地址 | hero 视频 |
PUBLIC_BRAND_HERO_PRODUCT_SLUG | hero 面板中展示的商品 | acme-ceramic-mug |
PUBLIC_API_BASE | 客户端请求使用的后端 API base | https://api.store-a.example.com/api/v1 |
RCOMMERCE_API_URL | 运行时 API 代理的后端源(不带 /api/v1 后缀) | — |
PUBLIC_AIRWALLEX_ENV | 结账 Drop-in 的 Airwallex 环境兜底值(demo/prod) | demo |
未设置时全部回退到示例店铺的默认值,因此不带任何环境变量构建 出来的就是演示店铺。
品牌内容系统
Section titled “品牌内容系统”面向用户的长文案(标语、联系页面、页脚链接与栏目、首页文案、
FAQ)位于 src/lib/brand/:
default.ts—— 完整的示例店铺内容,BrandContent类型的 每个字段都有值。store-b.ts—— 店铺B 的覆盖项,只写不同的字段。index.ts—— 将defaultContent与PUBLIC_BRAND_SLUG选中的 覆盖模块深合并:
export const content: BrandContent = mergeContent(defaultContent, OVERRIDES[brand.slug]);未知的 slug 原样回退到默认内容。接入新店铺只需新增一个
<slug>.ts 覆盖模块并注册进 OVERRIDES 映射,无需改动其他代码。
每家店铺必须提供自己的 logo(public/images/<store>-logo.png),
不要用其他店铺的 logo 顶替。
品牌内容中还包含 wooRedirects —— 遗留 WooCommerce 商品 slug 到
规范商品 URL 的映射,参见 SEO 与重定向。
运行时 API 代理
Section titled “运行时 API 代理”客户端请求直接使用 PUBLIC_API_BASE,但购物车、优惠券、结账等
写操作走同源代理 /api/v1/*(src/pages/api/v1/[...path].ts,
一个 Pages Function)。它运行时转发到 RCOMMERCE_API_URL,避免在
浏览器侧暴露凭据和 CORS 问题。
- 商品目录:分类导航 + 商品详情页
- 游客购物车(抽屉式)+ 优惠券
- 结账:物流选择 + Airwallex Drop-in
- 账户页面:注册、登录、重置密码、订单历史
- 按源站(origin)自动生成的
robots.txt、sitemap.xml和 Google shopping feed - 为迁移店铺准备的遗留 WooCommerce URL 301 重定向