All skills
wix avatar

/wix-app

@dc6f1fa official
by Wix.comwix/skills33 stars
33

Build and review Wix CLI app extensions — dashboard pages, modals, plugins, menu plugins, custom element widgets, Editor React components, site plugins, embedded scripts, backend APIs, backend events, service plugins, data collections, and App Market readiness. Use when building ANY feature or extension for a Wix CLI app or preparing a Wix app for App Market review. Triggers on: add, build, create, implement, help me, dashboard, widget, plugin, backend, API, event, collection, embedded script, service plugin, Editor React component, checkout, shipping, tax, discount, SPI, CMS, schema, tracking, popup, admin panel, menu item, modal, validate, test, verify, register extension, App Market, app review, submission readiness.

Use this Skill: https://skilld.dev/gh/wix/skills/wix-app

This session only. Nothing lands on disk.

referencessite-pluginEXAMPLES.md

≈2.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Site Plugin Examples

Complete examples showing all required files for site plugins.

Best Seller Badge Plugin

A customizable badge that displays on product pages with configurable text and colors.

Plugin Component (best-seller-badge.tsx)

class BestSellerBadge extends HTMLElement {
  static get observedAttributes() {
    return ['badge-text', 'bg-color', 'text-color'];
  }

  constructor() {
    super();
  }

  connectedCallback() {
    this.render();
  }

  attributeChangedCallback() {
    this.render();
  }

  render() {
    const badgeText = this.getAttribute('badge-text') || 'Best Seller';
    const bgColor = this.getAttribute('bg-color') || '#ff6b35';
    const textColor = this.getAttribute('text-color') || '#ffffff';

    this.innerHTML = `
      <span style="
        display: inline-block;
        padding: 8px 16px;
        background-color: ${bgColor};
        color: ${textColor};
        font-weight: bold;
        border-radius: 4px;
        font-size: 14px;
        text-transform: uppercase;
        letter-spacing: 1px;
      ">${badgeText}</span>
    `;
  }
}

export default BestSellerBadge;

Settings Panel (best-seller-badge.panel.tsx)

import React, { type FC, useState, useEffect, useCallback } from 'react';
import { widget, inputs } from '@wix/editor';
import {
  SidePanel,
  WixDesignSystemProvider,
  Input,
  FormField,
  Box,
  FillPreview,
} from '@wix/design-system';
import '@wix/design-system/styles.global.css';

const Panel: FC = () => {
  const [badgeText, setBadgeText] = useState<string>('');
  const [bgColor, setBgColor] = useState<string>('#ff6b35');
  const [textColor, setTextColor] = useState<string>('#ffffff');

  useEffect(() => {
    Promise.all([
      widget.getProp('badge-text'),
      widget.getProp('bg-color'),
      widget.getProp('text-color'),
    ])
      .then(([text, bg, color]) => {
        setBadgeText(text || 'Best Seller');
        setBgColor(bg || '#ff6b35');
        setTextColor(color || '#ffffff');
      })
      .catch(error => console.error('Failed to fetch props:', error));
  }, []);

  const handleTextChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const newText = event.target.value;
    setBadgeText(newText);
    widget.setProp('badge-text', newText);
  }, []);

  const handleBgColorChange = useCallback((value: string) => {
    setBgColor(value);
    widget.setProp('bg-color', value);
  }, []);

  const handleTextColorChange = useCallback((value: string) => {
    setTextColor(value);
    widget.setProp('text-color', value);
  }, []);

  return (
    <WixDesignSystemProvider>
      <SidePanel width="300" height="100vh">
        <SidePanel.Content noPadding stretchVertically>
          <SidePanel.Field>
            <FormField label="Badge Text">
              <Input
                type="text"
                value={badgeText}
                onChange={handleTextChange}
                aria-label="Badge Text"
              />
            </FormField>
          </SidePanel.Field>
          <SidePanel.Field>
            <FormField label="Background Color">
              <Box width="30px" height="30px">
                <FillPreview
                  fill={bgColor}
                  onClick={() => inputs.selectColor(bgColor, { onChange: (val) => { if (val) handleBgColorChange(val); } })}
                />
              </Box>
            </FormField>
          </SidePanel.Field>
          <SidePanel.Field>
            <FormField label="Text Color">
              <Box width="30px" height="30px">
                <FillPreview
                  fill={textColor}
                  onClick={() => inputs.selectColor(textColor, { onChange: (val) => { if (val) handleTextColorChange(val); } })}
                />
              </Box>
            </FormField>
          </SidePanel.Field>
        </SidePanel.Content>
      </SidePanel>
    </WixDesignSystemProvider>
  );
};

export default Panel;

Extension Configuration (best-seller-badge.extension.ts)

import { extensions } from '@wix/astro/builders';

export default extensions.sitePlugin({
  id: 'f8e2a1b3-c4d5-6789-abcd-ef0123456789',
  name: 'Best Seller Badge',
  marketData: {
    name: 'Best Seller Badge',
    description: 'Display a customizable badge on product pages',
    logoUrl: '{{BASE_URL}}/best-seller-badge-logo.svg',
  },
  placements: [
    {
      appDefinitionId: '1380b703-ce81-ff05-f115-39571d94dfcd',
      widgetId: '13a94f09-2766-3c40-4a32-8edb5acdd8bc',
      slotId: 'product-page-details-2',
    },
    {
      appDefinitionId: 'a0c68605-c2e7-4c8d-9ea1-767f9770e087',
      widgetId: '6a25b678-53ec-4b37-a190-65fcd1ca1a63',
      slotId: 'product-page-details-2',
    },
  ],
  installation: { autoAdd: true },
  tagName: 'best-seller-badge',
  element: './extensions/site/plugins/best-seller-badge/best-seller-badge.tsx',
  settings: './extensions/site/plugins/best-seller-badge/best-seller-badge.panel.tsx',
});

Dashboard Page for Plugin Management

For plugins that require back-office management (especially checkout and side cart plugins that may not support auto-add), create a dashboard page.

Note: The placement option in addSitePlugin() is optional. If omitted, the plugin is placed in the first available slot based on the priority order configured in the plugin's installation settings in your app's dashboard.

// src/extensions/dashboard/pages/plugin-settings/page.tsx
import { dashboard } from "@wix/dashboard";
import { Page, WixDesignSystemProvider, Card, FormField, Input, Button } from "@wix/design-system";

export default function PluginSettingsPage() {
  const handleAddToSlot = async () => {
    const pluginId = "your-plugin-id";
    const pluginPlacement = {
      appDefinitionId: "host-app-definition-id",
      widgetId: "host-widget-id",
      slotId: "target-slot-id",
    };

    await dashboard.addSitePlugin(pluginId, {
      placement: pluginPlacement,
    });
    dashboard.showToast({ message: "Plugin added!", type: "success" });
  };

  return (
    <WixDesignSystemProvider>
      <Page>
        <Page.Header title="Plugin Settings" />
        <Page.Content>
          <Card>
            <Card.Header title="Manage Your Plugin" />
            <Card.Content>
              <Button onClick={handleAddToSlot}>Add Plugin to Slot</Button>
            </Card.Content>
          </Card>
        </Page.Content>
      </Page>
    </WixDesignSystemProvider>
  );
}

Wix Data API Integration

When using Wix Data API in plugins, handle the Wix Editor environment. This example imports @wix/site-window — install it first (npm install @wix/site-window), since it's not part of the CLI's default scaffolded package.json:

import { items } from "@wix/data";
import { window as wixWindow } from "@wix/site-window";

class DataPlugin extends HTMLElement {
  static get observedAttributes() {
    return ['collection-id'];
  }

  constructor() {
    super();
  }

  connectedCallback() {
    this.render();
    this.loadData();
  }

  attributeChangedCallback() {
    this.loadData();
  }

  render() {
    this.innerHTML = `
      <div style="padding: 16px; border: 1px solid #ccc; border-radius: 8px;">
        <p>Loading...</p>
      </div>
    `;
  }

  async loadData() {
    const collectionId = this.getAttribute('collection-id');
    if (!collectionId) return;

    try {
      const viewMode = await wixWindow.viewMode();

      if (viewMode === 'Editor') {
        this.innerHTML = `
          <div style="padding: 20px; border: 2px dashed #ccc;">
            <p>Plugin will display data on the live site</p>
            <p>Collection: ${collectionId}</p>
          </div>
        `;
        return;
      }

      const results = await items.query(collectionId).limit(10).find();
      this.innerHTML = `
        <div style="padding: 16px;">
          ${results.items.map(item => `<div>${item.title}</div>`).join('')}
        </div>
      `;
    } catch (error) {
      console.error('Failed to load data:', error);
      this.innerHTML = `<div style="color: red;">Error loading data</div>`;
    }
  }
}

export default DataPlugin;

Example Use Cases

Booking Confirmation Message Plugin

Request: "Create a plugin for booking pages that shows a custom confirmation message"

Output:

  • Plugin with configurable title, message, and styling
  • Settings panel with text inputs and color pickers
  • Responsive layout that fits the booking page slot

Product Reviews Summary Plugin

Request: "Create a plugin that displays a reviews summary on product pages"

Output:

  • Plugin showing star rating and review count
  • Configurable display options (show count, show average)
  • Settings panel for styling customization
  • Integration with slot on product page
  • Include placements for both old and new Wix Stores product page versions

Source: SKILL.md on GitHub

1 warningtoday4 checks · Risk SAFE
  • Gen Agent Trust Hubtoday

    This skill is a specialized development toolkit for building extensions on the Wix platform. It provides comprehensive instructions for creating dashboard pages, backend APIs, and site plugins using the Wix CLI and SDKs. No malicious patterns were detected; the skill's behaviors, such as dependency management, command execution for builds, and local script execution for code reviews, are entirely consistent with its purpose as a developer productivity tool for the Wix ecosystem.

  • Sockettoday

    1 alert: gptAnomaly

  • Snyktoday

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at dc6f1fa. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 2 days ago
compatibility
requires `@wix/cli` >= 1.1.192.

README badge

README badge for wix/skills/wix-app

Builds dashboard pages, modals, plugins, custom widgets, Editor React components, backend APIs, events, service plugins, and data collections for Wix CLI apps. Provides decision logic, API patterns, and validation workflows; scaffolding is owned by the Wix CLI via `wix generate --params`.

Generated from the current SKILL.md.

What extension types does this skill cover?
All Wix CLI app extension types: dashboard pages, modals, plugins, menu plugins, custom element widgets, Editor React components, site plugins, embedded scripts, backend APIs, backend events, service plugins, and data collections.
Does this skill scaffold the extension files for me?
The Wix CLI owns scaffolding via `wix generate --params` for all extension types except Backend API. This skill provides decision logic, API guidance, and business-logic patterns to fill in the generated stubs. Backend API files must be created manually.
What Wix CLI version is required?
The skill requires @wix/cli >= 1.1.192.
Do I need to create a Data Collection extension for app-specific data?
Yes, if you're saving or persisting app-specific data, managing domain entities in a dashboard, or running a service plugin that reads app-configured data. The skill infers this automatically—you don't need to explicitly request it.
Does this skill cover Wix Stores API usage?
Yes. When using any Wix Stores API (products, inventory, orders), the skill requires dual V1/V3 catalog support and references the Stores Versioning guide for module selection and field mapping.

Generated from the current SKILL.md. These answers refresh after source changes.