mcpField
W
wix-cli-site-plugin

wix-cli-site-plugin

github.com/wix開発36288 回インストール今日更新
リポジトリ

wix-cli-site-plugin について

wix-cli-site-pluginは、Wix CLIアプリ向けのサイトプラグイン開発スキルです。Wixの各ソリューションのスロットに配置するカスタム要素、エディター設定パネル、拡張機能の登録方法を案内します。

主な機能

  1. 01カスタム要素プラグインの構成
  2. 02Wix Editor設定パネル
  3. 03スロット配置と登録
  4. 04プロパティと属性の連携
  5. 05カラー・フォントピッカー

活用シーン

  1. 01商品ページに設定可能なバッジを追加
  2. 02予約ページに確認メッセージを表示
  3. 03商品レビューの概要を表示

インストール

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

$npx skills add https://github.com/wix/skills --skill wix-cli-site-plugin

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

同梱ファイルreferences/EXAMPLES.mdreferences/SLOTS.md

詳細

Wix サイトプラグインビルダー

Wix CLI アプリケーション向けのサイトプラグイン拡張機能を作成します。サイトプラグインは、Wix のビジネスソリューション(Wix Stores、Wix Bookings、Wix eCommerce など)にあらかじめ定義されたスロットに統合され、機能とユーザーエクスペリエンスを拡張するカスタム要素です。

サイトオーナーは、Wix エディターのプラグインエクスプローラーを使用して、サイトプラグインを UI スロットに配置できます。

クイックスタートチェックリスト

サイトプラグインを作成するときは、次の手順を順番に実行してください。

  1. プラグインフォルダーを作成します:src/extensions/site/plugins/<plugin-name>/
  2. observedAttributes を実装した HTMLElement を拡張する <plugin-name>.tsx を作成します
  3. WDS コンポーネントと widget.getProp/setProp を使用する <plugin-name>.panel.tsx を作成します
  4. extensions.sitePlugin() と一意の UUID を使用する <plugin-name>.extension.ts を作成します
  5. src/extensions.ts を更新し、新しい拡張機能をインポートして使用します

アーキテクチャ

サイトプラグインは必須ファイル 3 つで構成されます。

1. プラグインコンポーネント(<plugin-name>.tsx)

ネイティブの HTMLElement を使用して、スロット内に表示されるカスタム要素コンポーネントです。

  • HTMLElement クラスを拡張します
  • リアクティブなプロパティ用に observedAttributes を定義します
  • レンダリング用に connectedCallback() と attributeChangedCallback() を実装します
  • テンプレート文字列を使ってインラインスタイルを指定します
  • 属性にはケバブケースを使用します(例:display-name)
2. 設定パネル(<plugin-name>.panel.tsx)

Wix エディターのサイドバーに表示される設定パネルです。

  • Wix Design System(@wix/design-system)のコンポーネントを使用します。コンポーネントのリファレンスについては、wds-docs を参照してください
  • @wix/editor のウィジェット API を使ってプラグインのプロパティを管理します
  • widget.getProp('kebab-case-name') で初期値を読み込みます
  • widget.setProp('kebab-case-name', value) でプロパティを更新します
  • ウィジェットのプロパティはカスタム要素の属性にバインドされているため、プロパティを変更すると対応する属性が自動的に更新されます
  • WixDesignSystemProvider > SidePanel > SidePanel.Content でラップします
3. 拡張機能の設定(<plugin-name>.extension.ts)

プラグインの配置設定を定義します。

  • プラグインを追加できるスロットを指定します
  • アプリのインストール時に自動追加する動作を設定します
  • タグ名とファイルパスを設定します

プラグインコンポーネントのパターン

サイトプラグインでは、ネイティブの HTMLElement カスタム要素を使用します。

// my-site-plugin.tsx
class MyElement extends HTMLElement {
  static get observedAttributes() {
    return ['display-name'];
  }

  constructor() {
    super();
  }

  connectedCallback() {
    this.render();
  }

  attributeChangedCallback() {
    this.render();
  }

  render() {
    const displayName = this.getAttribute('display-name') || "Your Plugin's Title";

    this.innerHTML = `
      <div style="font-size: 16px; padding: 16px; border: 1px solid #ccc; border-radius: 8px; margin: 16px;">
        <h2>${displayName}</h2>
        <hr />
        <p>
          This is a Site Plugin generated by Wix CLI.<br />
          Edit your element's code to change this text.
        </p>
      </div>
    `;
  }
}

export default MyElement;

重要なポイント:

  • HTMLElement クラスを直接拡張します
  • リアクティブな属性を列挙する observedAttributes 静的ゲッターを定義します
  • 属性にはケバブケースを使用します(例:display-name、bg-color)
  • 初回レンダリング用に connectedCallback() を実装します
  • 属性の変更時に再レンダリングするため、attributeChangedCallback() を実装します
  • テンプレート文字列を使ってインラインスタイルを指定します
  • this.getAttribute('attribute-name') を使って属性値を読み取ります
  • define() は Wix が処理するため、コード内で customElements.define() を呼び出さないでください

設定パネルのパターン

// my-site-plugin.panel.tsx
import React, { type FC, useState, useEffect, useCallback } from 'react';
import { widget } from '@wix/editor';
import {
  SidePanel,
  WixDesignSystemProvider,
  Input,
  FormField,
} from '@wix/design-system';
import '@wix/design-system/styles.global.css';

const Panel: FC = () => {
  const [displayName, setDisplayName] = useState<string>('');

  useEffect(() => {
    widget.getProp('display-name')
      .then(displayName => setDisplayName(displayName || "Your Plugin's Title"))
      .catch(error => console.error('Failed to fetch display-name:', error));
  }, [setDisplayName]);

  const handleDisplayNameChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const newDisplayName = event.target.value;
    setDisplayName(newDisplayName);
    widget.setProp('display-name', newDisplayName);
  }, [setDisplayName]);

  return (
    <WixDesignSystemProvider>
      <SidePanel width="300" height="100vh">
        <SidePanel.Content noPadding stretchVertically>
          <SidePanel.Field>
            <FormField label="Display Name">
              <Input
                type="text"
                value={displayName}
                onChange={handleDisplayNameChange}
                aria-label="Display Name"
              />
            </FormField>
          </SidePanel.Field>
        </SidePanel.Content>
      </SidePanel>
    </WixDesignSystemProvider>
  );
};

export default Panel;

重要なポイント:

  • widget.getProp() と widget.setProp() のプロパティ名にはケバブケースを使用します(例:"display-name")
  • onChange ハンドラーでは、ローカル状態とウィジェットのプロパティの両方を必ず更新します
  • ウィジェットのプロパティはカスタム要素の属性にバインドされているため、変更すると対応する属性が自動的に更新されます
  • コンテンツは WixDesignSystemProvider > SidePanel > SidePanel.Content でラップします
  • @wix/design-system の WDS コンポーネントを使用します
  • スタイルには @wix/design-system/styles.global.css をインポートします
  • アクセシビリティのために aria-label を含めます

カラーおよびフォントのピッカーフィールド

サイトプラグインの設定パネルでは、@wix/editor の inputs.selectColor() と inputs.selectFont() を使用して、Wix エディター標準のカラーおよびフォントピッカーダイアログを開けます。

ColorPickerField

テーマカラーやグラデーションなどを含む Wix カラーピッカーを開きます。基本的な HTML の <input type="color"> ではありません。

import React, { type FC } from 'react';
import { inputs } from '@wix/editor';
import { FormField, Box, FillPreview, SidePanel } from '@wix/design-system';

interface ColorPickerFieldProps {
  label: string;
  value: string;
  onChange: (value: string) => void;
}

export const ColorPickerField: FC<ColorPickerFieldProps> = ({
  label,
  value,
  onChange,
}) => (
  <SidePanel.Field>
    <FormField label={label}>
      <Box width="30px" height="30px">
        <FillPreview
          fill={value}
          onClick={() => inputs.selectColor(value, { onChange: (val) => { if (val) onChange(val); } })}
        />
      </Box>
    </FormField>
  </SidePanel.Field>
);
FontPickerField

フォントファミリー、サイズ、太字、斜体などのタイポグラフィ機能を備えた Wix フォントピッカーを開きます。

import React, { type FC } from 'react';
import { inputs } from '@wix/editor';
import { FormField, Button, Text, SidePanel } from '@wix/design-system';

interface FontValue {
  font: string;
  textDecoration: string;
}

interface FontPickerFieldProps {
  label: string;
  value: FontValue;
  onChange: (value: FontValue) => void;
}

export const FontPickerField: FC<FontPickerFieldProps> = ({
  label,
  value,
  onChange,
}) => (
  <SidePanel.Field>
    <FormField label={label}>
      <Button
        size="small"
        priority="secondary"
        onClick={() => inputs.selectFont(value, { onChange: (val) => onChange({ font: val.font, textDecoration: val.textDecoration || "" }) })}
        fullWidth
      >
        <Text size="small" ellipsis>Change Font</Text>
      </Button>
    </FormField>
  </SidePanel.Field>
);

重要:

  • 必ず @wix/editor の inputs.selectColor() を FillPreview とともに使用してください。<Input type="color"> は使用しないでください。
  • 必ず @wix/editor の inputs.selectFont() を、コールバックパターン inputs.selectFont(value, { onChange }) で使用してください。
  • inputs は @wix/sdk ではなく、@wix/editor からインポートしてください。

属性の命名規則

サイトプラグインでは、HTML 属性に一貫して kebab-case を使用します。

ファイル規則例
<plugin>.tsx(getAttribute)kebab-casethis.getAttribute('display-name')
<plugin>.tsx(observedAttributes)kebab-case['display-name', 'bg-color']
<plugin>.panel.tsx(ウィジェット API)kebab-casewidget.getProp('display-name')

出力構成

サイトプラグインは src/extensions/site/plugins の下に配置します。各プラグインには専用のフォルダーがあり、その中のファイルにはプラグイン名が付けられています。

src/extensions/site/plugins/
└── {plugin-name}/
    ├── {plugin-name}.tsx           # Main plugin component (HTMLElement)
    ├── {plugin-name}.panel.tsx     # Settings panel component
    └── {plugin-name}.extension.ts  # Extension registration
public/
└── {plugin-name}-logo.svg          # Plugin logo (optional)

参考資料

トピック参考資料
完全な例EXAMPLES.md
スロット(アプリ ID、複数の配置場所、スロットの確認方法)SLOTS.md
WDS コンポーネントwds-docs

利用可能なスロット

サイトプラグインは、Wix のビジネスソリューションにあらかじめ定義されたスロットに統合されます。各スロットは次の要素で識別されます。

  • appDefinitionId:Wix アプリの ID(例:Stores、Bookings)
  • widgetId:スロットを含むページの ID
  • slotId:個々のスロットを識別する ID

一般的な配置場所には、商品ページ(Wix Stores)、チェックアウトおよびサイドカート(Wix eCommerce)、予約ページ(Wix Bookings)、サービスページ、イベントページ、ブログ記事ページなどがあります。

対応ページ、一般的な Wix アプリ ID、スロット ID の確認方法については、SLOTS.md を参照してください。

拡張機能の登録

拡張機能の登録は必須であり、2 つの手順が必要です。

ステップ 1:プラグイン固有の拡張ファイルを作成する

各サイトプラグインには、そのフォルダー内に拡張ファイルが必要です。

// my-site-plugin.extension.ts
import { extensions } from '@wix/astro/builders';

export default extensions.sitePlugin({
  id: '{{GENERATE_UUID}}',
  name: 'My Site Plugin',
  marketData: {
    name: 'My Site Plugin',
    description: 'Marketing Description',
    logoUrl: '{{BASE_URL}}/my-site-plugin-logo.svg',
  },
  placements: [{
    appDefinitionId: 'a0c68605-c2e7-4c8d-9ea1-767f9770e087',
    widgetId: '6a25b678-53ec-4b37-a190-65fcd1ca1a63',
    slotId: 'product-page-details-6',
  }],
  installation: { autoAdd: true },
  tagName: 'my-site-plugin',
  element: './extensions/site/plugins/my-site-plugin/my-site-plugin.tsx',
  settings: './extensions/site/plugins/my-site-plugin/my-site-plugin.panel.tsx',
});

重要:UUID の生成

id は一意で固定の UUID v4 文字列である必要があります。拡張ごとに新しい UUID を生成してください。randomUUID() を使用したり、例にある UUID をコピーしたりしないでください。{{GENERATE_UUID}} を、"95a28afd-7df1-4e09-9ec1-ce710b0389a0" のように新しく生成した UUID に置き換えてください。

プロパティ型説明
idstring一意で固定の UUID v4(新しく生成)
namestringプラグインの内部名
marketData.namestringプラグインエクスプローラーとアプリダッシュボードに表示される名前
marketData.descriptionstringプラグインエクスプローラーとアプリダッシュボードに表示される説明
marketData.logoUrlstringロゴファイルへのパス({{BASE_URL}} は public フォルダーに解決されます)
placementsarrayプラグインを追加できるスロット配置の配列
placements.appDefinitionIdstringスロットを含む Wix アプリの ID
placements.widgetIdstringスロットを含むページの ID
placements.slotIdstring特定のスロットの ID
installation.autoAddbooleanアプリのインストール時にプラグインをスロットへ自動追加するかどうか
tagNamestringHTML カスタム要素のタグ(ケバブケース。ハイフンを含める必要があります)
elementstringプラグインコンポーネントへの相対パス
settingsstring設定パネルコンポーネントへの相対パス
ステップ 2:メインの拡張ファイルに登録する

重要: プラグイン固有の拡張ファイルを作成したら、wix-cli-extension-registration を必ず読み、「App Registration」セクションの手順に従って src/extensions.ts を更新してください。

ステップ 2 を完了しないと、サイトプラグインはプラグインエクスプローラーで利用できません。

チェックアウトプラグイン

チェックアウトページ用のプラグインを作成する場合、インストール時の自動追加に対応していないことがあります。ユーザーがプラグインをサイトに追加する方法を提供するために、ダッシュボードページを作成する必要があります。ダッシュボードページのパターンについては、EXAMPLES.md を参照してください。

例

必要な 3 つのファイル(プラグインコンポーネント、設定パネル、拡張設定)をすべて含む完全な例については、EXAMPLES.md を参照してください。

ユースケースの例:

  • ベストセラーバッジ - テキストと色を設定できる、商品ページ用のカスタマイズ可能なバッジ
  • 予約確認 - 予約ページ用のカスタム確認メッセージ
  • 商品レビューの概要 - 星評価とレビュー件数の表示
  • データ駆動型プラグイン - Wix Data API との連携とエディター環境への対応を備えたプラグイン

ベストプラクティス

実装ガイドライン
  • インラインスタイルを使用する - カスタム要素では CSS のインポートはサポートされていません
  • エディター環境に対応する - データに依存するプラグインでは、エディターモード時にプレースホルダーを表示します
  • define() を呼び出さない - customElements.define() は Wix が自動的に処理します
  • すべての入力を検証する - 必須のプロパティが存在することを確認します
  • 命名規則に従う - すべての属性とウィジェット API にケバブケースを使用します
  • プラグインの目的を絞る - 各プラグインは 1 つの機能を適切に果たすようにします
  • 複数のスロットでテストする - 複数の配置に対応する場合は、それぞれをテストします
  • 両方の Stores バージョンをサポートする - 最大限の互換性を確保するため、旧バージョンと新バージョンの両方の Wix Stores 商品ページ用の配置を含めます
エディターのサンドボックス化

サイトプラグインは、エディターでレンダリングされる際にサンドボックス化されます。つまり、別のドメインから読み込まれたかのように扱われるため、ブラウザーのストレージ API へのアクセスに影響します。

エディターで制限される API:

  • localStorage および sessionStorage(Web Storage API)
  • document.cookie(Cookie Store API)
  • IndexedDB API
  • Cache API

サンドボックス化への対処方法:

制限される API にアクセスする前に、@wix/site-window の viewMode() 関数を使って現在のモードを確認します。

import { window as wixWindow } from '@wix/site-window';

const viewMode = await wixWindow.viewMode();

if (viewMode === 'Site') {
  const item = localStorage.getItem('myKey');
} else {
  // Mock storage or modify API usage for editor mode
}
サイトプラグインでの Wix SDK モジュールの使用

サイトプラグインでは、Wix SDK モジュールを直接インポートして使用できます。createClient() を使用する必要はありません。Wix ランタイムによって、クライアントコンテキストが自動的に提供されます。

// ✅ CORRECT — Import SDK modules directly
import { items } from "@wix/data";
import { currentCart } from "@wix/ecom";
import { products } from "@wix/stores";

class MyPlugin extends HTMLElement {
  async loadData() {
    // Call SDK methods directly — no createClient needed
    const result = await items.query("MyCollection").find();
    const cart = await currentCart.getCurrentCart();
    const productList = await products.queryProducts().limit(10).find();
  }
}
// ❌ WRONG — Do NOT use createClient in site plugins
import { createClient } from "@wix/sdk";
const wixClient = createClient({ modules: { items, products } });
await wixClient.items.query(...); // Wrong — API surface differs through client
パフォーマンスに関する考慮事項
  • バンドルサイズを小さく保ちます。プラグインはユーザー向けページで読み込まれます。
  • 初回レンダリング時の負荷の高い計算は避けます。
  • 可能な場合は、データを遅延読み込みします。
  • 効率的な再レンダリングのパターンを使用します。

コメント