faststore-overrides

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

FastStore Section & Component Overrides

FastStore 区块与组件覆盖

When this skill applies

本技能的适用场景

Use this skill when:
  • You need to customize the behavior or appearance of a FastStore storefront component beyond what theming and design tokens can achieve.
  • You need to replace a native component entirely with a custom implementation.
  • You need to inject custom logic or modify props on native components within a section.
  • You are working with files in
    src/components/overrides/
    .
Do not use this skill for:
  • Visual-only changes (colors, typography, spacing) — use the
    faststore-theming
    skill and design tokens instead.
  • Building custom state management for cart, session, or search — use the
    faststore-state-management
    skill.
  • Extending the GraphQL data layer — use the
    faststore-data-fetching
    skill.
本技能适用于以下场景:
  • 你需要对FastStore店铺前端组件进行定制,且定制需求超出了主题和设计令牌的能力范围。
  • 你需要用自定义实现完全替换原生组件。
  • 你需要在某个区块内的原生组件中注入自定义逻辑或修改props。
  • 你正在处理
    src/components/overrides/
    目录下的文件。
本技能不适用于以下场景:
  • 仅视觉层面的修改(颜色、排版、间距)——请使用
    faststore-theming
    技能和设计令牌。
  • 为购物车、会话或搜索构建自定义状态管理——请使用
    faststore-state-management
    技能。
  • 扩展GraphQL数据层——请使用
    faststore-data-fetching
    技能。

Decision rules

决策规则

  • Use overrides when theming alone cannot achieve the desired change (e.g., replacing a component, adding logic, changing behavior).
  • Use the
    components
    map with
    { Component: CustomComponent }
    when replacing a native component entirely.
  • Use the
    components
    map with
    { props: { ... } }
    when only changing props on a native component without replacing it.
  • Use the
    className
    option on
    getOverriddenSection()
    for wrapper-level styling alongside behavioral changes.
  • Prefer theming with design tokens for purely visual changes — overrides are heavier and more tightly coupled.
  • Only override components listed as overridable in the FastStore native sections documentation. Undocumented component names are silently ignored.
  • Components prefixed with
    __experimental
    can be overridden but their props are not accessible and may change without notice.
  • 当仅靠主题定制无法实现预期修改时(例如替换组件、添加逻辑、更改行为),使用覆盖方案。
  • 当需要完全替换原生组件时,使用
    components
    映射并配置
    { Component: CustomComponent }
  • 当仅需修改原生组件的属性而不替换组件时,使用
    components
    映射并配置
    { props: { ... } }
  • 当需要在修改行为的同时进行容器级样式调整时,在
    getOverriddenSection()
    中使用
    className
    选项。
  • 对于纯视觉修改,优先使用设计令牌进行主题定制——覆盖方案更重且耦合性更强。
  • 仅能覆盖FastStore原生区块文档中列出的可覆盖组件。未记录的组件名称会被静默忽略。
  • 前缀为
    __experimental
    的组件可以被覆盖,但它们的props不可访问,且可能会无预警地变更。

Hard constraints

硬性约束

Constraint: Use the Override API — Never Modify FastStore Core

约束:使用覆盖API——切勿修改FastStore核心代码

MUST use
getOverriddenSection()
from
@faststore/core
to customize sections. MUST NOT directly modify files in
node_modules/@faststore/
or import internal source files.
Why this matters Modifying
node_modules
is ephemeral (changes are lost on
npm install
) and importing from internal paths like
@faststore/core/src/
creates tight coupling to implementation details that can break on any FastStore update.
Detection If you see imports from
@faststore/core/src/
(internal source paths) → STOP. These are private implementation details. Only import from the public API:
@faststore/core
and
@faststore/core/experimental
. If you see direct file edits in
node_modules/@faststore/
→ STOP immediately and use the override system instead.
Correct
typescript
// src/components/overrides/ProductDetails.tsx
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

import CustomProductTitle from '../CustomProductTitle'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    ProductTitle: { Component: CustomProductTitle },
  },
})

export default OverriddenProductDetails
Wrong
typescript
// WRONG: Importing from internal source paths
import { ProductDetails } from '@faststore/core/src/components/sections/ProductDetails'
// This path is an implementation detail that can change without notice.
// It bypasses the public API and will break on FastStore updates.

// WRONG: Modifying node_modules directly
// Editing node_modules/@faststore/core/dist/components/ProductDetails.js
// Changes are lost on every npm install and cannot be version-controlled.

必须使用
@faststore/core
中的
getOverriddenSection()
来定制区块。严禁直接修改
node_modules/@faststore/
中的文件或导入内部源文件。
重要性说明 修改
node_modules
中的内容是临时的(执行
npm install
后更改会丢失),而从
@faststore/core/src/
这类内部路径导入会与实现细节产生强耦合,FastStore的任何更新都可能导致代码失效。
问题检测 如果发现从
@faststore/core/src/
(内部源路径)导入的代码→立即停止。这些是私有实现细节。只能从公开API导入:
@faststore/core
@faststore/core/experimental
。如果发现直接编辑
node_modules/@faststore/
中的文件→立即停止,改用覆盖系统。
正确示例
typescript
// src/components/overrides/ProductDetails.tsx
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

import CustomProductTitle from '../CustomProductTitle'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    ProductTitle: { Component: CustomProductTitle },
  },
})

export default OverriddenProductDetails
错误示例
typescript
// 错误:从内部源路径导入
import { ProductDetails } from '@faststore/core/src/components/sections/ProductDetails'
// 该路径是实现细节,可能会无预警变更。
// 这种方式绕过了公开API,FastStore更新时会失效。

// 错误:直接修改node_modules
// 编辑node_modules/@faststore/core/dist/components/ProductDetails.js
// 更改会在每次执行npm install时丢失,且无法进行版本控制。

Constraint: Override Files Must Live in src/components/overrides/

约束:覆盖文件必须放在src/components/overrides/目录下

MUST place override files in the
src/components/overrides/
directory, named after the section being overridden (e.g.,
ProductDetails.tsx
).
Why this matters FastStore's build system scans
src/components/overrides/
to discover and apply section overrides. Files placed elsewhere will not be detected and the override will silently fail — the native section will render instead with no error message.
Detection If you see override-related code (calls to
getOverriddenSection
) in files outside
src/components/overrides/
→ warn that the override will not be applied. Check that the filename matches a valid native section name from the FastStore section list.
Correct
typescript
// src/components/overrides/Alert.tsx
// File is in the correct directory and named after the Alert section
import { getOverriddenSection } from '@faststore/core'
import { AlertSection } from '@faststore/core'

import CustomIcon from '../CustomIcon'

const OverriddenAlert = getOverriddenSection({
  Section: AlertSection,
  components: {
    Icon: { Component: CustomIcon },
  },
})

export default OverriddenAlert
Wrong
typescript
// src/components/MyCustomAlert.tsx
// WRONG: File is NOT in src/components/overrides/
// FastStore will NOT discover this override.
// The native Alert section will render unchanged.
import { getOverriddenSection } from '@faststore/core'
import { AlertSection } from '@faststore/core'

const OverriddenAlert = getOverriddenSection({
  Section: AlertSection,
  components: {
    Icon: { Component: CustomIcon },
  },
})

export default OverriddenAlert

必须将覆盖文件放在
src/components/overrides/
目录中,文件名与要覆盖的区块名称一致(例如
ProductDetails.tsx
)。
重要性说明 FastStore的构建系统会扫描
src/components/overrides/
目录来发现并应用区块覆盖。放在其他位置的文件不会被检测到,覆盖会静默失效——原生区块会正常渲染,且不会有错误提示。
问题检测 如果在
src/components/overrides/
目录外的文件中发现与覆盖相关的代码(调用
getOverriddenSection
)→警告该覆盖不会生效。检查文件名是否与FastStore区块列表中的有效原生区块名称一致。
正确示例
typescript
// src/components/overrides/Alert.tsx
// 文件在正确的目录中,且以Alert区块命名
import { getOverriddenSection } from '@faststore/core'
import { AlertSection } from '@faststore/core'

import CustomIcon from '../CustomIcon'

const OverriddenAlert = getOverriddenSection({
  Section: AlertSection,
  components: {
    Icon: { Component: CustomIcon },
  },
})

export default OverriddenAlert
错误示例
typescript
// src/components/MyCustomAlert.tsx
// 错误:文件不在src/components/overrides/目录下
// FastStore不会发现此覆盖。
// 原生Alert区块会保持不变地渲染。
import { getOverriddenSection } from '@faststore/core'
import { AlertSection } from '@faststore/core'

const OverriddenAlert = getOverriddenSection({
  Section: AlertSection,
  components: {
    Icon: { Component: CustomIcon },
  },
})

export default OverriddenAlert

Constraint: Override Only Documented Overridable Components

约束:仅覆盖有文档记录的可覆盖组件

MUST only override components listed as overridable in the FastStore native sections documentation. Components prefixed with
__experimental
can be overridden but their props are not accessible.
Why this matters Attempting to override a component not listed as overridable will silently fail. The override configuration will be ignored and the native component will render. Components marked
__experimental
have unstable prop interfaces that may change without notice.
Detection If you see a component name in the
components
override map that does not appear in the FastStore list of overridable components for that section → warn that this override may not work. If the component is prefixed with
__experimental
→ warn about inaccessible props and instability.
Correct
typescript
// src/components/overrides/ProductDetails.tsx
// ProductTitle is a documented overridable component of ProductDetails section
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    ProductTitle: {
      props: {
        refNumber: true,
        showDiscountBadge: false,
      },
    },
  },
})

export default OverriddenProductDetails
Wrong
typescript
// src/components/overrides/ProductDetails.tsx
// "InternalPriceCalculator" is NOT a documented overridable component
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    // This component name does not exist in the overridable list.
    // The override will be silently ignored.
    InternalPriceCalculator: { Component: MyPriceCalculator },
  },
})

export default OverriddenProductDetails
只能覆盖FastStore原生区块文档中列出的可覆盖组件。前缀为
__experimental
的组件可以被覆盖,但它们的props不可访问。
重要性说明 尝试覆盖未记录为可覆盖的组件会静默失效。覆盖配置会被忽略,原生组件会正常渲染。标记为
__experimental
的组件其属性接口不稳定,可能会无预警变更。
问题检测 如果在
components
覆盖映射中发现的组件名称未出现在FastStore对应区块的可覆盖组件列表中→警告该覆盖可能无法生效。如果组件前缀为
__experimental
→警告其props不可访问且存在不稳定性。
正确示例
typescript
// src/components/overrides/ProductDetails.tsx
// ProductTitle是ProductDetails区块中有文档记录的可覆盖组件
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    ProductTitle: {
      props: {
        refNumber: true,
        showDiscountBadge: false,
      },
    },
  },
})

export default OverriddenProductDetails
错误示例
typescript
// src/components/overrides/ProductDetails.tsx
// "InternalPriceCalculator"不是有文档记录的可覆盖组件
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    // 该组件名称不在可覆盖列表中。
    // 此覆盖会被静默忽略。
    InternalPriceCalculator: { Component: MyPriceCalculator },
  },
})

export default OverriddenProductDetails

Preferred pattern

推荐模式

Recommended file layout:
text
src/
├── components/
│   ├── overrides/
│   │   ├── ProductDetails.tsx    ← override file (named after section)
│   │   ├── Alert.tsx
│   │   └── simple-alert.module.scss
│   ├── CustomBuyButton.tsx       ← custom component
│   └── BoldIcon.tsx
Minimal override — replace a component:
typescript
// src/components/overrides/ProductDetails.tsx
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

import CustomBuyButton from '../CustomBuyButton'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    BuyButton: { Component: CustomBuyButton },
  },
})

export default OverriddenProductDetails
Override props without replacing the component:
typescript
// src/components/overrides/ProductDetails.tsx
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    BuyButton: {
      props: {
        size: 'small',
        iconPosition: 'left',
      },
    },
  },
})

export default OverriddenProductDetails
Override with custom styling:
typescript
// src/components/overrides/Alert.tsx
import { getOverriddenSection } from '@faststore/core'
import { AlertSection } from '@faststore/core'
import styles from './simple-alert.module.scss'

import BoldIcon from '../BoldIcon'

const OverriddenAlert = getOverriddenSection({
  Section: AlertSection,
  className: styles.simpleAlert,
  components: {
    Icon: { Component: BoldIcon },
  },
})

export default OverriddenAlert
推荐的文件结构:
text
src/
├── components/
│   ├── overrides/
│   │   ├── ProductDetails.tsx    ← 覆盖文件(以区块命名)
│   │   ├── Alert.tsx
│   │   └── simple-alert.module.scss
│   ├── CustomBuyButton.tsx       ← 自定义组件
│   └── BoldIcon.tsx
最小化覆盖——替换组件:
typescript
// src/components/overrides/ProductDetails.tsx
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

import CustomBuyButton from '../CustomBuyButton'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    BuyButton: { Component: CustomBuyButton },
  },
})

export default OverriddenProductDetails
覆盖属性但不替换组件:
typescript
// src/components/overrides/ProductDetails.tsx
import { getOverriddenSection } from '@faststore/core'
import { ProductDetailsSection } from '@faststore/core'

const OverriddenProductDetails = getOverriddenSection({
  Section: ProductDetailsSection,
  components: {
    BuyButton: {
      props: {
        size: 'small',
        iconPosition: 'left',
      },
    },
  },
})

export default OverriddenProductDetails
带自定义样式的覆盖:
typescript
// src/components/overrides/Alert.tsx
import { getOverriddenSection } from '@faststore/core'
import { AlertSection } from '@faststore/core'
import styles from './simple-alert.module.scss'

import BoldIcon from '../BoldIcon'

const OverriddenAlert = getOverriddenSection({
  Section: AlertSection,
  className: styles.simpleAlert,
  components: {
    Icon: { Component: BoldIcon },
  },
})

export default OverriddenAlert

Common failure modes

常见失败模式

  • Monkey-patching
    node_modules/@faststore/
    or using
    patch-package
    for changes the override system supports. Changes are lost on install and create maintenance burden.
  • Using CSS
    !important
    to force visual changes instead of the override API for behavioral changes or design tokens for visual changes.
  • Creating wrapper components around native sections instead of using
    getOverriddenSection()
    . Wrappers bypass CMS integration, analytics tracking, and section discovery.
  • Placing override files outside
    src/components/overrides/
    — they will be silently ignored.
  • Overriding a component name not listed in the FastStore overridable components documentation — the override is silently ignored.
  • 对覆盖系统支持的修改,采用猴子补丁修改
    node_modules/@faststore/
    或使用
    patch-package
    。更改会在安装时丢失,且增加维护负担。
  • 使用CSS
    !important
    强制修改视觉效果,而非针对行为变更使用覆盖API或针对视觉变更使用设计令牌。
  • 在原生区块外创建包装组件,而非使用
    getOverriddenSection()
    。包装组件会绕过CMS集成、分析跟踪和区块发现功能。
  • 将覆盖文件放在
    src/components/overrides/
    目录外——会被静默忽略。
  • 覆盖FastStore可覆盖组件文档中未列出的组件名称——覆盖会被静默忽略。

Review checklist

审核检查清单

  • Is the override file located in
    src/components/overrides/
    and named after the target section?
  • Does the file use
    getOverriddenSection()
    from
    @faststore/core
    ?
  • Are all overridden component names documented as overridable for that section?
  • Are imports only from
    @faststore/core
    or
    @faststore/core/experimental
    (not internal source paths)?
  • Could this change be achieved with design tokens instead of an override?
  • Does the override export as default?
  • 覆盖文件是否位于
    src/components/overrides/
    目录下,且与目标区块同名?
  • 文件是否使用了
    @faststore/core
    中的
    getOverriddenSection()
  • 所有被覆盖的组件名称是否都是对应区块中有文档记录的可覆盖组件?
  • 导入是否仅来自
    @faststore/core
    @faststore/core/experimental
    (而非内部源路径)?
  • 该变更是否可以通过设计令牌而非覆盖实现?
  • 覆盖是否以默认导出的形式对外暴露?

Reference

参考资料