---
name: wix-app
description: "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."
compatibility: requires `@wix/cli` >= 1.1.192.
---
# Wix App Builder
Helps build extensions for Wix CLI applications. Covers all extension types: dashboard pages, modals, plugins, menu plugins, custom element widgets, Editor React components, site plugins, embedded scripts, backend APIs, events, service plugins, and data collections.
**Scaffolding is owned by the Wix CLI.** Use `wix generate --params` for every supported type. It generates files and, where applicable, builder boilerplate, UUIDs, and `src/extensions.ts` registration. HTTP endpoints are discovered from files and need no registration. This skill provides the decision logic, API guidance, configuration semantics, and business-logic patterns that fill in the generated stubs.
## ⚠️ MANDATORY WORKFLOW CHECKLIST ⚠️
**Before reporting completion to the user, ALL boxes MUST be checked:**
- [ ] **Step 1:** Determined extension type(s) needed
- [ ] Asked clarifying questions if requirements were unclear
- [ ] **🛑 SDK-First Gate (MANDATORY before any Data Collection):** Confirmed the data is NOT owned by an existing Wix app — if it is, use its SDK module, never CMS (see [SDK-First Rule](#sdk-first-rule-existing-wix-app-data-is-never-cms))
- [ ] Checked for implicit Data Collection need — unless user provided a collection ID directly (see [Data Collection Inference](#data-collection-inference))
- [ ] Obtained app namespace if Data Collection extension is being created
- [ ] Determined full scoped collection IDs if Data Collection extension is being created (see [Collection ID Coordination](#collection-id-coordination))
- [ ] Explained recommendation with reasoning
- [ ] **Step 2:** Read extension reference file(s) for the chosen type(s) and the project-wide [CODE_QUALITY.md](references/CODE_QUALITY.md)
- [ ] **Dashboard page UI:** Translated the prompt into a workflow before choosing components — what the user must understand, focus on, investigate, act on, and see confirmed. See [UX Success Model](references/dashboard-page/UX_SUCCESS_MODEL.md), and the installed package's own `Collection Toolkit.md` guide for which component serves each need ([The Discovery Chain](references/WIX_PATTERNS_DOCS.md#the-discovery-chain)).
- [ ] **A row the user can open** — WDS `SidePanel` to inspect without losing the filtered list, or `EntityPage` for deep or shareable detail — unless the prompt is explicitly a report or an export.
- [ ] **Every filter reaches the query**: declared in the collection hook's `filters` and read inside `fetchData`. Filter UI that never narrows the rows is a defect that looks like a feature.
A filtered table with neither of the two is what gets built when nobody states the requirement — it is the most common way a generated dashboard disappoints.
- [ ] **🛑 Patterns Docs Gate (MANDATORY for any dashboard page UI):** Read [WIX_PATTERNS_DOCS.md](references/WIX_PATTERNS_DOCS.md), then **probe** `dist/docs/index.json` with `grep`/`python3` — never a whole-file `Read`, which truncates it silently. It is the one file that says, per symbol, where to import it from (`importPath`), whether its props live in the doc or in a `.d.ts` (`bundle`), and which worked examples exist (`examples`). Upgrade `@wix/patterns` if that file is missing. Patterns API facts come only from the published `dist/docs/` (pages), `dist/examples/` (worked calls) and `dist/dts-bundle/` (types) trees — never from `src/`, `dist/esm/`, or any other path inside the package, with one named exception: `dist/types/` when a bundle has stubbed the prop you need (WIX_PATTERNS_DOCS.md step 5).
- [ ] **🛑 Component Docs Gate (MANDATORY, dashboard UI only):** For each patterns symbol you are about to write, decided **from the index** which single artifact answers the question you actually have, and read that one — not all three:
- **Where do I import it from?** → the entry's `importPath`. No file read at all.
- **How do I call it?** (generics, what a callback receives and returns, how the pieces nest) → the **example** named in `examples`. One worked example beats reconstructing a call from a chain of type files; a hook's example is often filed under the component it pairs with.
- **What props, and which are optional?** → **the example first** — it shows the props in use, correctly typed. For what an example cannot show (optionality, union members, an exact callback signature): entry has `bundle` ⇒ read that `.d.ts`; entry has no `bundle` ⇒ the doc's own table is complete and marks `Required`, so read the doc. The two are mutually exclusive — reading both is always one hop too many. **Two thirds of bundles stub the parent that holds the props** (`propsTotal` far above what the file declares is the tell); when that happens, read the parent the index names — one hop — batch any `readWith` files you still need into a single call, and fall back to `dist/types/` for the declaration `tsc` enforces. WIX_PATTERNS_DOCS.md step 5 has the procedure.
- **Any setup requirement or gotcha?** → the doc's prose. Rare, but load-bearing where present (routers, providers).
State which artifact you read per symbol, and why, before the first line of JSX. Reading a doc *and* its bundle for the same symbol, or opening a page for an `importPath` the index already gave you, is the failure this gate exists to prevent.
- [ ] **Step 3:** Checked API references; used MCP discovery only for gaps
- [ ] Site/editor extensions only: kept SDK calls in the extension by default, routing out only business-wide methods a visitor genuinely cannot call (see [Identity and Elevation Requirement](#identity-and-elevation-requirement))
- [ ] **Step 4a:** Scaffolded each CLI-supported extension via `wix generate --params`
- [ ] **Step 4b:** Filled in business logic in the generated files
- [ ] **🛑 Component Selection Gate (MANDATORY, dashboard UI only):** For every UI element on a Dashboard Page, resolved it against `@wix/patterns` BEFORE reaching for `@wix/design-system` — and never hand-rolled a component either library already provides. See [Component Selection Order](#component-selection-order).
- [ ] Invoked `wix-design-system` skill ONLY before editing the first `.tsx`/`.jsx` file that imports `@wix/design-system`. Skip for backend-only or data-only extensions.
- [ ] WDS: imported `@wix/design-system/styles.global.css` in the main component entry file (`page.tsx`, modal `.tsx`, etc.) — not child/tab/helper files.
- [ ] **Step 5:** Ran validation (see [Validation](#validation))
- [ ] Dependencies installed
- [ ] TypeScript compiled
- [ ] Build succeeded
- [ ] Preview deployed
- [ ] **Step 6:** Collected and presented ALL manual action items to user
**🛑 STOP:** If any box is unchecked, do NOT proceed to the next step.
---
## ❌ ANTI-PATTERNS (DO NOT DO)
| ❌ WRONG | ✅ CORRECT |
| ------------------------------------------- | ---------------------------------------------- |
| Creating a CMS Data Collection for data an existing Wix app already owns (orders, products, bookings, contacts…), or deciding "no SDK exists" without a single MCP search | Use the domain's SDK module per the [SDK-First Rule](#sdk-first-rule-existing-wix-app-data-is-never-cms) |
| Hand-writing builder files, folders, UUIDs, or extension registration | Run `wix generate --params` — it owns scaffolding |
| Implementing without reading the extension reference | Always read the relevant reference file first |
| Using MCP discovery without checking refs | Check reference files first |
| Reporting done without validation | Always run validation at the end |
| Letting manual action items get buried | Aggregate all manual steps at the very end |
| Building a dashboard page's collection UI (table, grid, filters, sort, bulk actions, page header) out of raw WDS or hand-written React | Use the `@wix/patterns` equivalent — it exists (see [Component Selection Order](#component-selection-order)) |
| Guessing a `@wix/patterns` or WDS component/prop name from memory | Look it up: patterns via `dist/docs/index.json` + `dist/dts-bundle/index.json` (see [WIX_PATTERNS_DOCS.md](references/WIX_PATTERNS_DOCS.md)), WDS via the `wix-design-system` skill |
| Hand-rolling a component (empty state, badge, tooltip, pagination) that one of the two libraries already ships | Search patterns first, then WDS; only build custom when both genuinely lack it |
| Calling `auth.elevate` from a site or editor extension, or calling an admin-only method there | Put the call in a backend extension and elevate there — elevation only works in backend code |
| Elevating a session-resolved `current*`/`my*` method (`currentCartV2.*`, `members.getMyMember`) to "be safe" | Call it directly — elevating replaces the caller's session identity and retargets the operation |
| Elevating a read the platform filters by caller (`members.getMember`/`queryMembers`, `items.*`, catalog) to "make it return more" | Call it directly — elevating removes the filter and returns data the visitor was never entitled to |
---
## Quick Decision Helper
1. **What are you trying to build?**
- Admin interface → Dashboard Extensions
- Backend logic → Backend Extensions
- Data storage / CMS collections → Data Collection (app-owned data only — see [SDK-First Rule](#sdk-first-rule-existing-wix-app-data-is-never-cms))
- Editor React component → Site Extensions (app projects only)
2. **Who will see it?**
- Admin users only → Dashboard Extensions
- Site visitors → Site Extensions
- Server-side only → Backend Extensions
3. **Where will it appear?**
- Dashboard sidebar/page →
- Full admin screen: Dashboard Page — UI built with `@wix/patterns` + `@wix/design-system` (see [Component Selection Order](#component-selection-order))
- Popup/form: Dashboard Modal
- Existing Wix app dashboard (widget) → Dashboard Plugin
- Existing Wix app dashboard (menu item) → Dashboard Menu Plugin
- Anywhere on site → custom element widget
- Anywhere on site (with editor manifest) → Editor React component
- Wix business solution page → Site Plugin
- During business flow → Service Plugin
- Exposing tools to the Wix AI assistant → App Tools
- After event occurs → Backend Event Extension
## Decision Flow (Not sure?)
- **Admin:** Admin screen in the site owner's dashboard? → Dashboard Page — build its UI with `@wix/patterns` first, `@wix/design-system` for whatever patterns does not cover (see [Component Selection Order](#component-selection-order)). Need popup/form? → Dashboard Modal. Extending Wix app dashboard with a visual widget? → Dashboard Plugin. Adding a menu item to a Wix app dashboard's more-actions or bulk-actions menu? → Dashboard Menu Plugin. **Modal constraint:** Dashboard Pages cannot use ``; use a separate Dashboard Modal extension and `dashboard.openModal()`.
- **Backend:** During business flow (checkout/shipping/tax)? → Service Plugin. Exposing tools to the Wix AI assistant? → App Tools (requires both `APP_TOOLS` declaration + `TOOLS_PROVIDER_CONFIG` handler — see [APP_TOOLS.md](references/APP_TOOLS.md)). After event (webhooks/sync)? → Backend Event Extension. Custom HTTP endpoints? → Backend API. Need CMS collections for app-owned data? → Data Collection (see [SDK-First Rule](#sdk-first-rule-existing-wix-app-data-is-never-cms)).
- **Site:** User places anywhere (standalone)? → custom element widget. Editor React component with editor manifest (styling, content, elements)? → Editor React component. Fixed slot on Wix app page? → Site Plugin. Scripts/analytics only? → Embedded Script.
---
## Component Selection Order
Dashboard pages at Wix are built from two libraries. For **every** UI element, resolve in this order and stop at the first hit. Never skip a step, and never decide a component is missing from memory — check.
### 1. `@wix/patterns` — page structure and data collections
Patterns owns the page shell and everything collection-shaped: page shells and their header /
content / footer sub-parts, tables and grids and the switch between them, folder views,
collection state (paging, sorting, selection, loading), filters, search, view presets, row and
bulk actions, drag-and-drop, in-extension routing, the overlays tied to a collection, and the
add / edit / view page for one listed item. If you need one of those, it is patterns' — look it
up rather than assembling it from WDS parts.
**Which component serves a given need is the library's own answer, not this skill's.** It ships
that answer as guides inside the installed package, with every component name in them checked
against the real package at build time. Walk them: [The Discovery Chain](references/WIX_PATTERNS_DOCS.md#the-discovery-chain).
The short version — probe `/dist/docs/index.json` first (`grep`/`python3`, not a
whole-file `Read`), then the guides it lists. From
there the index answers per symbol: `importPath` is the import line (no read needed), `examples`
names the worked call, and `bundle` says whether props live in a `.d.ts` or in the doc's own
table. Read the one artifact your open question needs. Resolve `` once per session
([Prerequisites](references/WIX_PATTERNS_DOCS.md#prerequisites)) and reuse it.
**Add / edit / view one item from a collection is an `EntityPage`, not a dashboard modal** — see
[Entity create and edit](#entity-create-and-edit), and `Collection to Entity Flow.md` in the
package for the flow itself.
**Falling through to step 2 because a lookup was inconvenient is the single most common way a
dashboard page ends up built entirely from WDS.** A missing index means the lookup has not
happened yet, not that patterns lacks the component.
### 2. `@wix/design-system` — everything inside the shell
The leaf-level UI patterns does not own: inputs, buttons, form fields, text, layout primitives, cards, badges, tooltips, toasts, icons. Pick the component by lookup, not recall — invoke the **`wix-design-system` skill**, whose bundled helper reads the installed package:
```bash
node /scripts/wds.cjs search
node /scripts/wds.cjs component
```
### 3. Custom React — only after both came back empty
Compose from WDS layout primitives (`Box`, `Card`, `Text`). Do not add a third UI dependency, and do not restyle patterns or WDS internals.
### Overlaps and scope
- When both libraries ship the same concept (page header, page container), the **patterns** one wins inside a patterns page — it is the piece wired into the shell's layout and collection state. Use the WDS equivalent only outside a patterns page shell.
- **Patterns has its own overlays.** `PickerModal` / `usePickerModal` and `bulkActionModal` cover collection-related overlays. "It's a modal" is not a reason to leave patterns.
- **Dashboard Plugins** render outside a patterns page shell, so WDS is the default there. Patterns collection components still apply when such a surface displays a data collection.
### Entity create and edit
**Any dialog that creates, updates, or displays one record listed by a collection page is an `EntityPage` — not a Dashboard Modal.** This holds whether the records come from a CMS collection or an existing Wix app's SDK. A create / "add new" form is included: it **writes** the record, so it is an `EntityPage` even though nothing is being edited yet. "It's a simple data-entry dialog, not an entity edit" is the wrong reading of this rule.
A page that lists nothing — a settings page, an embedded-script config page — carries no `EntityPage` obligation. But "I built the list without `@wix/patterns`" is not an exception: a page that lists records should be a `CollectionPage`.
This is the most common place the selection order gets dropped: the collection gets built correctly with patterns, then the "add item" flow is hand-built as a WDS form in a modal.
The documented flow:
1. From the collection page's action cell or primary action, call `navigateToEntityPage({ path, entity })` from `usePatternsNavigate()`. (The patterns docs give this exact use case — "navigate to an entity page on an action cell click on a collection page" — and it renders the entity header immediately, before the fetch resolves.) On the **create** route there is no record to pass: omit `entity` and read the **Create route** section of `/dist/docs/useEntityPage.md`, which is what the whole "add new" flow turns on.
2. Register the route with `PatternsReactRoute` inside `PatternsReactRouter`.
3. In the entity page, `useEntityPage({ fetch, onSave })` owns fetching, saving, validation, dirty state, loading skeletons, and error states. Form state comes from `useForm` / `useController` in `@wix/patterns/form`. The call itself — both generics, what `onSave` receives, which params exist — is in `/dist/docs/useEntityPage.md`.
4. Compose the body from `EntityPage.Header`, `EntityPage.MainContent`, `EntityPage.AdditionalContent`, and `EntityPage.Card`. **WDS goes inside those cards** — `FormField`, `Input`, `Text` for the individual fields.
Use a Dashboard Modal for dialogs that neither write nor display a listed record: a delete or discard confirmation, an unsaved-changes prompt, an informational notice, or any dialog on a page that lists nothing. Dialog size and field count are not exceptions — a one-field create form over a listed record is still an `EntityPage`. Reach for a modal because the interaction persists nothing, never because "the form should open in a modal."
---
## Extension Types Reference Table
| Extension Type | Category | `extensionType` (for `wix generate --params`) | Reference File |
| --- | --- | --- | --- |
| Dashboard Page | Dashboard | `DASHBOARD_PAGE` | [DASHBOARD_PAGE.md](references/DASHBOARD_PAGE.md) |
| Dashboard Modal | Dashboard | `DASHBOARD_MODAL` | [DASHBOARD_MODAL.md](references/DASHBOARD_MODAL.md) |
| Dashboard Plugin | Dashboard | `DASHBOARD_PLUGIN` | [DASHBOARD_PLUGIN.md](references/DASHBOARD_PLUGIN.md) |
| Dashboard Menu Plugin | Dashboard | `DASHBOARD_MENU_PLUGIN` | [DASHBOARD_MENU_PLUGIN.md](references/DASHBOARD_MENU_PLUGIN.md) |
| Service Plugin | Backend | `SERVICE_PLUGIN` | [SERVICE_PLUGIN.md](references/SERVICE_PLUGIN.md) |
| App Tools (AI assistant tools) | Backend | `APP_TOOLS`, then `SERVICE_PLUGIN` with `pluginType: TOOLS_PROVIDER_CONFIG` | [APP_TOOLS.md](references/APP_TOOLS.md) |
| Backend Event Extension | Backend | `EVENT` | [BACKEND_EVENT.md](references/BACKEND_EVENT.md) |
| Backend API (HTTP endpoint) | Backend | `HTTP_ENDPOINT` | [BACKEND_API.md](references/BACKEND_API.md) |
| Data Collection | Backend | `DATA_COLLECTION` | [DATA_COLLECTION.md](references/DATA_COLLECTION.md) |
| Editor React component | Site | `EDITOR_REACT_COMPONENT` | [EDITOR_REACT_COMPONENT.md](references/EDITOR_REACT_COMPONENT.md) |
| Custom element widget | Site | `CUSTOM_ELEMENT` | [CUSTOM_ELEMENT_WIDGET.md](references/CUSTOM_ELEMENT_WIDGET.md) |
| Site Plugin | Site | `SITE_PLUGIN` | [SITE_PLUGIN.md](references/SITE_PLUGIN.md) |
| Embedded Script | Site | `EMBEDDED_SCRIPT` | [EMBEDDED_SCRIPT.md](references/EMBEDDED_SCRIPT.md) |
**Key constraints:**
- Dashboard Page cannot use ``; use a separate Dashboard Modal and `dashboard.openModal()`.
> **HTTP endpoints:** Generate with `extensionType: "HTTP_ENDPOINT"` (not `BACKEND_API`). See [BACKEND_API.md](references/BACKEND_API.md) for project-specific directories, handler types, and frontend URLs.
## Extension Comparison
| Custom element widget vs Editor React component vs Site Plugin | Dashboard Page vs Modal | Service Plugin vs Event |
| -------------------------------------------------------------- | ----------------------- | ----------------------- |
| Custom element widget: standalone interactive component. Editor React component: React with editor manifest (CSS/data/elements). Plugin: fixed slot in Wix app page. | Page: full page. Modal: overlay; use for popups. | Service: during flow. Event: after event. |
---
## Cross-Cutting References
| Topic | Reference |
| --- | --- |
| Code Quality Requirements (applies to all generated code) | [CODE_QUALITY.md](references/CODE_QUALITY.md) |
| Extension Registration | [EXTENSION_REGISTRATION.md](references/EXTENSION_REGISTRATION.md) |
| App Validation | [APP_VALIDATION.md](references/APP_VALIDATION.md) |
| App Market Review | [APP_MARKET_REVIEW.md](references/APP_MARKET_REVIEW.md) |
| App Identifiers (Namespace, Code ID) | [APP_IDENTIFIERS.md](references/APP_IDENTIFIERS.md) |
| Wix Stores Versioning (V1/V3) | [STORES_VERSIONING.md](references/STORES_VERSIONING.md) |
| Official Documentation Links | [DOCUMENTATION.md](references/DOCUMENTATION.md) |
| Wix Patterns Dashboard Pages | [WIX_PATTERNS_DOCS.md](references/WIX_PATTERNS_DOCS.md) |
| Dashboard UX Success Model (what a good dashboard contains) | [UX_SUCCESS_MODEL.md](references/dashboard-page/UX_SUCCESS_MODEL.md) |
---
## SDK-First Rule (Existing Wix App Data Is Never CMS)
**CRITICAL:** Data owned by an existing Wix business app is read and written through that app's SDK module — NEVER modeled as a new CMS Data Collection. A custom collection for such data starts empty and stays disconnected from the real records (e.g., a "refunds dashboard" built on CMS shows an empty state while refunded orders exist in Wix eCommerce).
**Entity → SDK module map** (find the entity the user mentioned, use that package):
| Entity | SDK package |
| --- | --- |
| orders / carts / checkout / refund records / fulfillments | `@wix/ecom` — orders live here regardless of vertical |
| products / inventory / catalog | `@wix/stores` — ⚠️ V1/V3 check, see [STORES_VERSIONING.md](references/STORES_VERSIONING.md) |
| payments / refunds / disputes | `@wix/payments` |
| invoices / payment links / receipts | `@wix/get-paid` |
| gift cards | `@wix/gift-vouchers` |
| coupons | `@wix/marketing` |
| pricing plans / subscriptions | `@wix/pricing-plans` |
| bookings / services / staff / time slots | `@wix/bookings` |
| calendar events / schedules | `@wix/calendar` |
| table reservations | `@wix/table-reservations` |
| restaurant menus / online orders | `@wix/restaurants` |
| blog posts | `@wix/blog` |
| site events / tickets / RSVPs | `@wix/events` |
| reviews | `@wix/reviews` |
| comments | `@wix/comments` |
| groups | `@wix/groups` |
| online programs | `@wix/online-programs` |
| donations | `@wix/donations` |
| portfolio | `@wix/portfolio` |
| media files | `@wix/media` |
| contacts / labels / tasks | `@wix/crm` |
| members | `@wix/members` |
| inbox conversations | `@wix/inbox` |
| forms / form submissions | `@wix/forms` |
| loyalty points / rewards | `@wix/loyalty` |
| email marketing | `@wix/email-marketing` |
| notifications | `@wix/notifications` |
| analytics | `@wix/analytics-data` |
| automations | `@wix/automations` |
| SEO tags / redirects | `@wix/seo` |
| site search | `@wix/search` |
| secrets | `@wix/secrets` |
| locations / site properties | `@wix/business-tools` |
| app instances | `@wix/app-management` |
If the entity isn't listed or you're unsure, run `SearchWixSDKDocumentation` for it — **never conclude CMS with zero MCP calls**. CMS is only for data your app itself introduces (configuration, rules, app-specific records) that no Wix app manages.
---
## Data Collection Inference
**CRITICAL:** Data collections are often needed implicitly — don't wait for the user to explicitly say "create a CMS collection." Infer the need automatically.
**⚠️ Apply the [SDK-First Rule](#sdk-first-rule-existing-wix-app-data-is-never-cms) first** — the indicators below only apply to data your app itself owns, not to entities a Wix app already manages.
**Skip this section if the user provides a collection ID directly** (e.g., an existing site-level collection). In that case, use the provided ID as-is — no Data Collection extension or namespace scoping needed.
**Always include a Data Collection extension when ANY of these are true:**
| Indicator | Example |
| --- | --- |
| User mentions saving/storing/persisting app-specific data | "save the fee amount", "store product recommendations" |
| A dashboard page will **manage** (CRUD) domain entities | "dashboard to manage fees", "admin page to edit rules" |
| A service plugin reads app-configured data at runtime | "fetch fee rules at checkout", "look up shipping rates" |
| User mentions "dedicated database/collection" | "save in a dedicated database collection" |
| Multiple extensions reference the same custom data | Dashboard manages fees + service plugin reads fees |
**Why this matters:** Without the Data Collection extension, the collection won't be created when the app is installed, the Wix Data APIs may not work (code editor not enabled), and collection IDs won't be properly scoped to the app namespace.
**If data collection is inferred, follow the [App Namespace Requirement](#app-namespace-requirement) to obtain the namespace before proceeding.**
### App Namespace Requirement
When creating a Data Collection, you MUST ask the user for their app namespace from Wix Dev Center. This is a required parameter that must be obtained from the user's Dev Center dashboard and cannot be recommended or guessed.
If the user hasn't provided their app namespace, read [APP_IDENTIFIERS.md](references/APP_IDENTIFIERS.md) and give the user the instructions to obtain it.
### Collection ID Coordination
**Applies ONLY when a Data Collection extension is being created.** If the user provides a collection ID directly, use it as-is — no namespace scoping, no Data Collection extension needed.
When a Data Collection is created alongside other extensions that reference the same collections:
1. **Get the app namespace** (see App Namespace Requirement above)
2. **Determine the `idSuffix`** for each collection (the Data Collection reference documents the full ID format)
3. **Use the full scoped collection ID** (`/`) in all extensions that reference the collection via Wix Data API calls
---
## Wix Stores Versioning Requirement
**Applies when ANY Wix Stores API is used** (products, inventory, orders, etc.):
1. **Read the Stores Versioning reference** — see [STORES_VERSIONING.md](references/STORES_VERSIONING.md). It contains the module map, permissions cheatsheet, copy-paste dual-catalog recipes (list/get/create/update/delete products, inventory, categories), the V1→V3 field map, webhook mapping, and the major V3 gotchas. **Use it before searching SDK docs** — it covers the common 80%.
2. **All Stores operations must check catalog version first** using `getCatalogVersion()`
3. **Use the correct module** based on version: `productsV3` (V3) vs `products` (V1)
4. **Apps MUST support both V1 and V3** — single-version apps cannot list in the App Market and break on new sites
5. **Request both V1 and V3 permission scopes** for every Stores operation
This is non-negotiable — V1 and V3 are NOT backwards compatible.
---
## Identity and Elevation Requirement
**Applies whenever an extension calls a Wix SDK method.** Decide where the call runs before writing it.
Who the extension runs as decides everything below — the Category column in [Extension Types Reference Table](#extension-types-reference-table) tells you which one you have:
- **Site and editor extensions** — custom element widgets, site plugins, Editor React components, embedded scripts — run as the site visitor or member, never as the app.
- **Dashboard extensions** run as the Wix user — not as a site visitor, and not as the app.
- **Backend extensions** — Backend API, Backend Event, Service Plugin — run as the app.
**`auth.elevate` works only in backend code.** In a site, editor, or dashboard extension it doesn't work at all.
**Default: call the SDK directly from the extension.** Routing a call that didn't need it is not a harmless extra hop — it is how working features break. Sort by who the call acts for, never by its scope name:
- **Acts for the current visitor or member** — their cart, checkout, booking, order, reservation, or profile: `currentCartV2.*`, `cartV2.placeOrder`, `bookings.createBooking`, `members.getMyMember`, and anything else operating on "my" or "the current" entity. These resolve the actor from the caller's session, so elevating runs them as the app and detaches the result from the person who asked — an order with no buyer, a booking with no attendee.
- **The platform filters the result by caller** — an elevated call returns what the direct call withheld, so a "fix" for a sparse result becomes a leak. Wix Data `items.*` follows the collection's `dataPermissions` (scaffolded default: `itemRead: 'ANYONE'`, writes `'PRIVILEGED'` — fix writes with permissions, not routing; see [DATA_COLLECTION.md](references/DATA_COLLECTION.md)). Catalog reads return base fields to anyone, withholding `MERCHANT_DATA` and non-visible products unless the app holds `SCOPE.STORES.PRODUCT_READ_ADMIN`. `members.getMember`/`queryMembers` withhold `PRIVATE` members from visitor and member callers.
**Route out only when the method acts on the business as a whole**, which a visitor or member genuinely cannot do: `archiveLocation`, `queryLocations`, catalog and inventory writes, `bookings.confirmBooking`, order management. **When the method's docs show the call elevated, route it out and elevate there** — from any host, dashboard included, because `auth.elevate` only works in backend code, so the endpoint is the only place the documented pattern can run.
**When you're unsure, call it directly and let it fail.** A method a site extension may not call returns a permission error you see immediately; a method wrongly routed and elevated *succeeds* and silently returns the wrong data or acts for the wrong person. Some method pages carry a prose note that settles it — `get-my-member`: "This method requires visitor or member authentication." Authoritative when present, but only a minority of pages have one, so its absence decides nothing.
Two signals never settle it: the scope name — `locations.queryLocations` is `SCOPE.DC-MULTILOCATION.READ-LOCATIONS` yet admin-only, while `currentCartV2.addLineItemsToCurrentCart` carries `SCOPE.ECOM.MANAGE-ADMIN` yet is visitor-callable and breaks if elevated — and the SDK schema line's client prefix, which varies by docs channel for the same method, so carries nothing and isn't worth re-deriving.
Routing out means a Backend API endpoint that elevates and is reached with `httpClient.fetchWithAuth()`. Elevation bypasses Wix's permission check, so the endpoint must re-check the caller itself — see [Identity and Authorization](references/BACKEND_API.md#identity-and-authorization) for what each host can actually verify, and why an owner-only operation belongs in a dashboard extension instead.
Add the scope in Dev Center → **Permissions** (it isn't declared in a repo file) and report it under [Manual Steps Required](#-manual-steps-required).
---
## App Market Review
**Applies when a user wants to submit their app to the Wix App Market, list it publicly, prepare for App Market review, audit decline risk, or fix App Market review feedback.** Not needed for private apps or routine version releases.
Read [APP_MARKET_REVIEW.md](references/APP_MARKET_REVIEW.md) — it contains the full technical checklist, implementation notes with Wix doc links, and the review taxonomy IDs for traceability.
---
## Implementation Workflow
### Step 1: Ask Clarifying Questions (if needed)
Only ask for configuration values when **absolutely necessary** for the implementation to proceed. If a value can be configured later or added as a manual step, don't block on it.
If unclear on approach (placement, visibility, configuration, integration), ask clarifying questions. If the answer could change the extension type, wait for the response before proceeding. Otherwise, proceed with the best-fit extension type.
### Step 2: Make Your Recommendation
Use the Extension Types Reference Table and decision content above. State extension type and brief reasoning (placement, functionality, integration).
### Step 3: Read Extension Reference, Check API References, Then Discover (if needed)
**Workflow: Read extension reference → Check API references → Use MCP only for gaps.**
1. **Read the extension reference file** for the chosen extension type from the table above
2. **Identify required APIs** from user requirements
3. **Check relevant API reference files:**
- Backend events → `references/backend-event/COMMON-EVENTS.md`
- Wix Data → `references/data-collection/WIX_DATA.md`
- Dashboard SDK → `references/dashboard-page/DASHBOARD_API.md`
- Service Plugin SPIs → read `references/SERVICE_PLUGIN.md` together with the matching `references/service-plugin/.md` leaf
- App Tools (AI assistant tools) → read `references/APP_TOOLS.md`; it links to `references/app-tools/TOOLS.md` (declaration) and `references/service-plugin/TOOLS_PROVIDER.md` (handler)
4. **Verify the specific method/event exists** in references
5. **ONLY use MCP discovery if NOT found** in reference files
**Platform APIs (never discover - in references):**
- Wix Data, Dashboard SDK, Event SDK (common events), Service Plugin SPIs
**Vertical APIs (discover if needed):**
- Wix Stores (**⚠️ MUST use Stores Versioning reference** — V1/V3 catalog check required), Wix eCommerce, Wix Bookings, Wix Members, Wix Pricing Plans, third-party integrations — find the right `@wix/*` package in the [SDK-First Rule](#sdk-first-rule-existing-wix-app-data-is-never-cms) module map first, then discover methods via MCP
**Decision table:**
| User Requirement | Check References / Discovery Needed? | Reason / Reference File |
| ------------------------------------ | ------------------------------------ | --------------------------------------------------- |
| "Display store products" | ✅ YES (MCP discovery) | Wix Stores API — **include Stores Versioning reference** |
| "Dashboard for orders / refunds" | ✅ YES (MCP discovery) | Wix eCommerce API (`@wix/ecom`) — **NEVER a CMS collection** |
| "Show booking calendar" | ✅ YES (MCP discovery) | Wix Bookings API not in reference files |
| "Send emails to users" | ✅ YES (MCP discovery) | Wix Triggered Emails not in reference files |
| "Get member info" | ✅ YES (MCP discovery) | Wix Members API not in reference files |
| "Listen for cart events" | Check `COMMON-EVENTS.md` | MCP discovery only if event missing in reference |
| "Store data in collection" | WIX_DATA.md ✅ Found | ❌ Skip discovery (covered by reference) |
| "Create CMS collections for my app" | Data Collection reference | ❌ Skip discovery (covered by dedicated reference) |
| "Show dashboard toast" | DASHBOARD_API.md ✅ Found | ❌ Skip discovery |
| "Show toast / navigate" | DASHBOARD_API.md ✅ Found | ❌ Skip discovery |
| "UI only (forms, inputs)" | N/A (no external API) | ❌ Skip discovery |
| "Settings page with form inputs" | N/A (UI only, no external API) | ❌ Skip discovery |
| "Dashboard page with local state" | N/A (no external API) | ❌ Skip discovery |
**MCP Tools for discovery (when needed):**
- `SearchWixSDKDocumentation` - SDK methods and APIs (**Always use maxResults: 5**)
- `ReadFullDocsMethodSchema` - Full type schema for a specific SDK method (parameters, return type, permissions)
- `ReadFullDocsArticle` - Prose guides and conceptual articles only (not for SDK method signatures)
### Step 4a: Scaffold via the CLI
For each supported type, including HTTP endpoints, run `npx wix generate --params ''`. The command returns `{"success":true,"extensionType":"...","newFiles":[...]}` on success.
If the command fails because of unknown or invalid params, run `npx wix schema generate --type ` to print the JSON Schema for that extension type, fix the `--params` payload, and retry. Do not fall back to manual scaffolding. The one exception is `HTTP_ENDPOINT` on a CLI older than 1.1.243, which predates the generator but still supports the extension: create the endpoint file by hand as described in [BACKEND_API.md](references/BACKEND_API.md#generate-for-the-project-type).
**What the CLI does automatically:**
- Creates folders and stub files
- For registered extensions, generates a fresh UUID and updates `src/extensions.ts` with the import and `.use()` call
- For HTTP endpoints, creates the route file without changing `src/extensions.ts`
- Enforces naming rules (kebab-case, hyphen-required custom elements, etc.)
**HTTP endpoints:** Run `npx wix generate --params '{"extensionType":"HTTP_ENDPOINT","name":"hello"}'`, then implement the handler in the returned file. Follow [BACKEND_API.md](references/BACKEND_API.md); if the route does not respond, its troubleshooting hint shows how to confirm discovery from the build output.
### Step 4b: Fill in business logic
Open every path returned in `newFiles` and replace stubbed handler bodies / UI / queries with the user's actual logic, guided by the extension reference file's API and configuration sections.
- ⚠️ MANDATORY when using WDS: Invoke the `wix-design-system` skill **before editing your first `.tsx`/`.jsx` file that imports `@wix/design-system`**. Do NOT invoke it preemptively for backend-only or data-only jobs — it adds large content to context that you won't use.
- ⚠️ MANDATORY when using WDS: Add `import "@wix/design-system/styles.global.css";` in the **main component** entry file (`page.tsx`, modal `.tsx`, etc.) — not in child/tab/helper files.
- ⚠️ MANDATORY when using Data Collections: Use the EXACT collection ID from `idSuffix` (case-sensitive). If `idSuffix` is `"product-recommendations"`, use `/product-recommendations` NOT `productRecommendations`.
### Step 5: Run Validation
After all implementation is complete, you MUST run validation. See [APP_VALIDATION.md](references/APP_VALIDATION.md) for the complete validation workflow:
1. Package installation (detect package manager, run install)
2. TypeScript compilation check (`npx tsc --noEmit -p .`)
3. Build validation (`npx wix build`)
4. Preview deployment (`npx wix preview`)
**Do NOT report completion to the user until validation passes.**
If validation fails, fix the errors and re-validate until it passes.
### Step 6: Report Completion
Only after validation passes, provide a **concise summary section** at the top of your response:
```markdown
## ✅ Implementation Complete
[1-2 sentence description of what was built]
**Extensions Created:**
- [Extension 1 Name] - [Brief purpose]
- [Extension 2 Name] - [Brief purpose]
**Build Status:**
- ✅ Dependencies: [Installed / status message]
- ✅ TypeScript: [No compilation errors / status]
- ✅ Build: [Completed successfully / status]
- ✅/⚠️ Preview: [Running at URL / Failed - reason]
**⚠️ IMPORTANT: [X] manual step(s) required to complete setup** (see "Manual Steps Required" section below)
```
- If there are NO manual steps, state: "✅ No manual steps required — you're ready to go!"
### Step 7: Surface Manual Action Items
Present any manual steps the user must perform (e.g., configuring settings in the Wix dashboard, enabling permissions, setting up external services).
**Format:**
```markdown
## 🔧 Manual Steps Required
The following actions need to be done manually by you:
### 1. [Action Category/Title]
[Detailed description with specific instructions]
### 2. [Action Category/Title]
[Detailed description]
```
---
## Extension Registration
`wix generate --params` updates `src/extensions.ts` automatically for registered extensions. HTTP endpoints require no import or `.use()` call; the runtime discovers their files. For background, troubleshooting, and the manual recovery pattern when `src/extensions.ts` drifts, see [EXTENSION_REGISTRATION.md](references/EXTENSION_REGISTRATION.md).
---
## Validation
Execute these steps sequentially after all implementation is complete. See [APP_VALIDATION.md](references/APP_VALIDATION.md) for the complete guide.
1. **Package Installation** — Detect package manager, run install
2. **TypeScript Compilation** — `npx tsc --noEmit -p .`
3. **Build** — `npx wix build`
4. **Preview** — `npx wix preview`
Stop and report errors if any step fails. Check `.wix/debug.log` on failures.
---
## Cost Optimization
- **Let the CLI scaffold** — don't burn tokens describing folder layouts or builder boilerplate
- **Only run `wix schema generate --type `** when `wix generate --params` fails — don't pre-fetch it
- **Read extension reference first** — always read the relevant extension reference file before implementing
- **Check API references first** — read relevant API reference files before using MCP discovery
- **Skip discovery** when all required APIs are in reference files
- **maxResults: 5** for all MCP SDK searches
- **ReadFullDocsMethodSchema** for SDK method schemas; **ReadFullDocsArticle** for prose guides only
- **Invoke wix-design-system** first when using WDS (prevents import errors)
- **Patterns before WDS** for dashboard page UI — check `@wix/patterns` docs before building anything collection- or page-shaped (see [Component Selection Order](#component-selection-order))
## Documentation
For links to official Wix CLI documentation for all extension types, see [DOCUMENTATION.md](references/DOCUMENTATION.md).