mcpField
F
faststore-theming

faststore-theming

github.com/vtexデザイン・UI4782 回インストール2 週間前に更新
リポジトリ

faststore-theming について

faststore-themingは、FastStoreストアの色、タイポグラフィ、余白、境界線、コンポーネントの見た目を調整する開発者向けスキルです。デザイントークンとコンポーネントのデータ属性を軸に、テーマファイルの配置やセレクターの規則を示します。

主な機能

  1. 01グローバルおよびローカルトークンの使用
  2. 02data-fs-*属性によるコンポーネント指定
  3. 03所定のディレクトリへのテーマSCSS配置
  4. 04カスタムコンポーネントへのCSS Modules適用
  5. 05テーマ変更と動作オーバーライドの区別

活用シーン

  1. 01ストアのブランドカラーと書体の設定
  2. 02特定コンポーネントの外観調整
  3. 03FastStoreテーマの作成や保守
  4. 04コンポーネントのオーバーライド要否の判断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/vtex/skills --skill faststore-theming

インストール後、Claude Code で/faststore-themingを入力して読み込まれたか確認します。

詳細

FastStore のテーマ設定とデザイントークン

このスキルを使用する場面

次の場合にこのスキルを使用します:

  • FastStore ストアフロントの見た目(色、タイポグラフィ、余白、ボーダー、コンポーネント固有のスタイル)を変更する必要がある場合。
  • src/themes/ 内のファイルを編集する場合、または custom-theme.scss を作成する場合。
  • ローカルトークンと [data-fs-*] データ属性を使って、個々のコンポーネントのスタイルをカスタマイズする必要がある場合。
  • Brandless のデフォルトテーマをベースにブランドアイデンティティを設定する場合。

次の場合にはこのスキルを使用しないでください:

  • コンポーネントの置き換え、ロジックの注入、動作の変更が必要な場合 — faststore-overrides スキルを使用してください。
  • クライアント側の状態管理 — faststore-state-management スキルを使用してください。
  • データ取得または API の拡張 — faststore-data-fetching スキルを使用してください。

判断ルール

  • オーバーライドを検討する前に、まずテーマ設定を使用してください。より軽量で、保守しやすいためです。
  • 変更をストア全体に適用する場合(ブランドカラー、フォントファミリーなど)は、グローバルトークン(:root スコープ)を使用してください。
  • 変更が単一のコンポーネントに適用される場合(ボタンの背景色など)は、ローカルトークン([data-fs-*] スコープ)を使用してください。
  • コンポーネントの対象指定には [data-fs-*] データ属性を使用してください。.fs-* クラス名や汎用タグセレクターは使用しないでください。
  • すべてのテーマファイルを src/themes/ に配置し、custom-theme.scss をエントリーポイントにしてください。それ以外の場所にあるファイルは認識されません。
  • 16 進カラーコード、ピクセルサイズ、フォント値をハードコードする代わりに、var(--fs-*) を使ってデザイントークンを参照してください。
  • FastStore の構造的なスタイルとの競合を避けるため、カスタム(FastStore 以外の)コンポーネントには CSS モジュールを使用してください。

厳守事項

制約:インラインスタイルではなく、デザイントークンを使用する

FastStore コンポーネントのスタイリングには、デザイントークン(グローバルまたはローカル)を必ず使用してください。テーマ設定を目的として、FastStore コンポーネントにインラインの style={} プロパティを使用してはいけません。

重要な理由 インラインスタイルはデザイントークンの階層を迂回するため、テーマで上書きできず、レスポンシブブレークポイントにも対応せず、保守を困難にします。また、HTML にスタイルが埋め込まれるため、CSS キャッシュの効果も損ないます。デザイントークンを使えば一貫性を保ち、単一のファイルからストア全体を変更できます。

検出方法 FastStore ネイティブコンポーネント(@faststore/ui または @faststore/core からインポートされたコンポーネント)に style={{ または style={ が使われている場合 → テーマ設定システムを迂回していることを警告してください。代わりにデザイントークンまたは CSS モジュールの使用を提案してください。例外:FastStore UI ライブラリに含まれない完全なカスタムコンポーネントでは、インラインスタイルを使用できます。

正しい例

// src/themes/custom-theme.scss
// Override the BuyButton's primary background color using design tokens
[data-fs-buy-button] {
  --fs-button-primary-bkg-color: #e31c58;
  --fs-button-primary-bkg-color-hover: #c4174d;
  --fs-button-primary-text-color: var(--fs-color-text-inverse);

  [data-fs-button-wrapper] {
    border-radius: var(--fs-border-radius-pill);
  }
}

誤った例

// WRONG: Using inline styles on a FastStore component
import { BuyButton } from '@faststore/ui'

function ProductActions() {
  return (
    <BuyButton
      style={{ backgroundColor: '#e31c58', color: 'white', borderRadius: '999px' }}
    >
      Add to Cart
    </BuyButton>
  )
  // Inline styles bypass the design token hierarchy.
  // They cannot be changed store-wide from the theme file.
  // They do not respond to dark mode or other theme variants.
}

制約:テーマファイルは src/themes/ に配置する

カスタムテーマの SCSS ファイルは必ず src/themes/ ディレクトリに配置してください。プライマリテーマファイルの名前は custom-theme.scss にしてください。

重要な理由 FastStore のビルドシステムは src/themes/custom-theme.scss からテーマファイルをインポートします。それ以外の場所に配置されたファイルはビルドに取り込まれず、トークンのオーバーライドは反映されません。エラーは発生せず、代わりにデフォルトの Brandless テーマが表示されます。

検出方法 src/themes/ の外にある SCSS ファイルにトークンのオーバーライド宣言(--fs- で始まる変数)がある場合 → 反映されない可能性があることを警告してください。プロジェクトに src/themes/custom-theme.scss が存在しない場合 → カスタムテーマが有効になっていないことを警告してください。

正しい例

// src/themes/custom-theme.scss
// Global token overrides — applied store-wide
:root {
  --fs-color-main-0: #003232;
  --fs-color-main-1: #004c4c;
  --fs-color-main-2: #006666;
  --fs-color-main-3: #008080;
  --fs-color-main-4: #00b3b3;

  --fs-color-accent-0: #e31c58;
  --fs-color-accent-1: #c4174d;
  --fs-color-accent-2: #a51342;

  --fs-text-face-body: 'Inter', -apple-system, system-ui, BlinkMacSystemFont, sans-serif;
  --fs-text-face-title: 'Poppins', var(--fs-text-face-body);

  --fs-text-size-title-huge: 3.5rem;
  --fs-text-size-title-page: 2.25rem;
}

// Component-specific token overrides
[data-fs-price] {
  --fs-price-listing-color: #cb4242;
}

誤った例

// src/styles/my-theme.scss
// WRONG: This file is in src/styles/, not src/themes/
// FastStore will NOT import this file. Token overrides will be ignored.
:root {
  --fs-color-main-0: #003232;
  --fs-color-accent-0: #e31c58;
}

// Also WRONG: Creating a theme in the project root
// ./theme.scss — this will not be discovered by the build system

制約:コンポーネントのターゲティングにはデータ属性を使用する

テーマの SCSS ファイルでコンポーネントをターゲットにする場合、FastStore の data-fs-* データ属性を必ず使用してください。FastStore ネイティブコンポーネントをターゲットにするために、クラス名やタグセレクターを使用してはいけません。

重要な理由 FastStore コンポーネントでは、データ属性が公開スタイリング API として使用されます(例:data-fs-button、data-fs-price、data-fs-hero)。クラス名は実装の詳細であり、バージョン間で変更される可能性があります。データ属性を使用すれば、FastStore のアップデート後もテーマを維持できます。各コンポーネントのドキュメントのカスタマイズセクションには、使用可能なデータ属性が記載されています。

検出 FastStore コンポーネントのスタイル設定に .fs-* クラス名や汎用タグセレクター(button、h1、div)をターゲットとする CSS セレクターが使われている場合 → 脆弱性について警告してください。代わりに [data-fs-*] セレクターを使用するよう提案してください。

正しい例

// src/themes/custom-theme.scss
// Target the Hero section using its data attribute
[data-fs-hero] {
  --fs-hero-text-size: var(--fs-text-size-title-huge);
  --fs-hero-heading-weight: var(--fs-text-weight-bold);

  [data-fs-hero-heading] {
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  [data-fs-hero-image] {
    border-radius: var(--fs-border-radius);
    filter: brightness(0.9);
  }
}

誤った例

// src/themes/custom-theme.scss
// WRONG: Targeting by class names — these are internal and may change
.fs-hero {
  font-size: 3.5rem;
}

.fs-hero h1 {
  text-transform: uppercase;
}

// WRONG: Using generic tag selectors
section > div > h1 {
  font-weight: bold;
}
// These are fragile selectors that break when FastStore restructures its HTML.

推奨パターン

推奨されるファイル構成:

src/
└── themes/
    └── custom-theme.scss    ← main entry point (auto-imported by FastStore)

最小限のカスタムテーマ:

// src/themes/custom-theme.scss
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@600;700;800&display=swap');

// Global Token Overrides
:root {
  --fs-color-main-0: #003232;
  --fs-color-main-1: #004c4c;
  --fs-color-accent-0: #e31c58;
  --fs-color-accent-1: #c4174d;

  --fs-text-face-body: 'Inter', -apple-system, system-ui, sans-serif;
  --fs-text-face-title: 'Poppins', var(--fs-text-face-body);
}

// Component-specific overrides
[data-fs-button] {
  --fs-button-border-radius: var(--fs-border-radius-pill);

  &[data-fs-button-variant="primary"] {
    --fs-button-primary-bkg-color: var(--fs-color-accent-0);
    --fs-button-primary-bkg-color-hover: var(--fs-color-accent-1);
    --fs-button-primary-text-color: var(--fs-color-text-inverse);
  }
}

[data-fs-price] {
  --fs-price-listing-color: #cb4242;
  --fs-price-listing-text-decoration: line-through;
}

[data-fs-navbar] {
  --fs-navbar-bkg-color: var(--fs-color-main-0);
  --fs-navbar-text-color: var(--fs-color-text-inverse);
}

カスタム(FastStore 以外の)コンポーネントには、競合を避けるために CSS モジュールを使用してください。

// src/components/CustomBanner.module.scss
.customBanner {
  display: flex;
  align-items: center;
  gap: var(--fs-spacing-3); // Still reference FastStore tokens for consistency
  padding: var(--fs-spacing-4);
  background-color: var(--fs-color-main-0);
  color: var(--fs-color-text-inverse);
  border-radius: var(--fs-border-radius);
}

よくある失敗例

  • !important 宣言を使用する — 詳細度の行き詰まりを招き、デザイントークンのカスケード特性を損ないます。適切なセレクターの詳細度で、適切なトークンを使用してください。
  • var(--fs-*) トークンを参照せず、コンポーネントのスタイルに16進数カラー、ピクセルサイズ、フォント値を直接ハードコードする。変更をストア全体に反映できなくなります。
  • Tailwind、Bootstrap、カスタムのグローバルスタイルシートなど、FastStore の構造スタイルと競合し、CSS のペイロードを二重化する別の CSS システムを構築する。
  • テーマファイルを src/themes/ の外に配置する — ビルドシステムで検出されません。
  • [data-fs-*] データ属性ではなく、.fs-* クラス名や汎用タグセレクターを使って FastStore コンポーネントをターゲットにする。

レビューチェックリスト

  • テーマファイルは src/themes/custom-theme.scss に配置されていますか?
  • グローバルトークンのオーバーライドは :root スコープに配置されていますか?
  • コンポーネントレベルのオーバーライドでは、[data-fs-*] データ属性セレクターを使用していますか?
  • すべての値はハードコードせず、var(--fs-*) を使ってデザイントークンを参照していますか?
  • !important 宣言を使用していませんか?
  • オーバーライドを使わずにこの変更を実現できますか(テーマ設定で十分ですか)?
  • カスタムコンポーネントのスタイルは、競合を避けるために CSS モジュールでスコープ化されていますか?

参考資料

コメント