@wix/agent-skills 1.24.0 → 1.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +1 -0
  2. package/package.json +2 -1
  3. package/skills/wix-app/SKILL.md +16 -14
  4. package/skills/wix-app/references/BUSINESS_MANAGER_THEME.md +107 -0
  5. package/skills/wix-app/references/BUSINESS_MANAGER_TOKENS.md +81 -0
  6. package/skills/wix-app/references/DASHBOARD_MODAL.md +41 -0
  7. package/skills/wix-app/references/DASHBOARD_PAGE.md +13 -11
  8. package/skills/wix-app/references/DASHBOARD_PLUGIN.md +19 -4
  9. package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +3 -2
  10. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +66 -68
  11. package/skills/wix-app/references/dashboard-page/DYNAMIC_PARAMETERS.md +21 -38
  12. package/skills/wix-app/references/data-collection/LIFECYCLE.md +6 -4
  13. package/skills/wix-headless/SKILL.md +0 -1
  14. package/skills/wix-headless/references/CAPABILITIES.md +3 -3
  15. package/skills/wix-headless/references/DISCOVERY.md +1 -1
  16. package/skills/wix-headless/references/SDK_HANDOFF.md +1 -1
  17. package/skills/wix-headless/references/SEED.md +1 -1
  18. package/skills/wix-headless/references/SETUP.md +1 -1
  19. package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-reservations.md +1 -1
  20. package/skills/wix-headless/references/inline-recipes/setup-restaurant-experiences.md +2 -2
  21. package/skills/wix-headless/references/managed/AUTHENTICATION.md +3 -14
  22. package/skills/wix-headless/scripts/bootstrap.mjs +156 -0
  23. package/skills/wix-headless-kit/SKILL.md +4 -4
  24. package/skills/wix-headless-kit/install/AGENTS.md +2 -2
  25. package/skills/wix-headless-kit/install/bootstrap.mjs +156 -0
  26. package/skills/wix-headless-kit/install/check.mjs +1 -1
  27. package/skills/wix-manage/SKILL.md +2 -8
  28. package/skills/wix-manage/references/cms/cms-data-items-crud.md +250 -18
  29. package/skills/wix-manage/references/cms/cms-schema-management.md +52 -1
  30. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_COLLECTION.md +0 -184
  31. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_ROUTER.md +0 -203
  32. package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE_SETTINGS.md +0 -44
  33. package/skills/wix-manage/references/cms/cms-data-operations-extended.md +0 -263
  34. package/skills/wix-manage/references/cms/cms-references-and-relationships.md +0 -162
@@ -1,203 +0,0 @@
1
- # Draft Template — Cases A, B and D (router-wired)
2
-
3
- **Applies to [DRAFT_TEMPLATE.md](DRAFT_TEMPLATE.md)'s Cases A, B and D.** All three need `PatternsReactRouter`, because in all three a row opens a page of its own — a panel is not the drill-in ([UX_SUCCESS_MODEL.md](UX_SUCCESS_MODEL.md)). Case A's detail route is read-only (§4); B and D route to a full `EntityPage`. The collection and settings components live in [DRAFT_TEMPLATE.md](DRAFT_TEMPLATE.md); this file covers only what a router adds — the entry file, the app shell, and the detail/entity page.
4
-
5
- Every snippet below is copied from the installed `dist/docs/*.md` this session read, not from memory.
6
-
7
- ## 1. Entry — `location` is manual in a Wix CLI app, and only because the router needs it
8
-
9
- `PatternsReactRouter` reads the page location through `container.usePageLocation()`, which only `withDashboard`'s `location` prop feeds — nothing supplies it automatically in a Wix CLI app the way Yoshi BM flow does:
10
-
11
- ```tsx
12
- // {feature}.tsx — Case A, B or D
13
- import { useEffect, useState, type FC } from 'react';
14
- import { dashboard } from '@wix/dashboard';
15
- import { WixDesignSystemProvider } from '@wix/design-system';
16
- import '@wix/design-system/styles.global.css';
17
- import { {Feature}App } from './{Feature}App';
18
-
19
- type PageLocation = Parameters<Parameters<typeof dashboard.observeState>[0]>[1]['pageLocation'];
20
-
21
- const Page: FC = () => {
22
- const [location, setLocation] = useState<PageLocation | undefined>();
23
-
24
- useEffect(() => {
25
- const subscription = dashboard.observeState((_pageParams, environment) => {
26
- setLocation(environment.pageLocation);
27
- });
28
- return () => subscription.disconnect();
29
- }, []);
30
-
31
- return (
32
- <WixDesignSystemProvider>
33
- {location ? <{Feature}App location={location} /> : null}
34
- </WixDesignSystemProvider>
35
- );
36
- };
37
-
38
- export default Page;
39
- ```
40
-
41
- **Skipping this is a runtime-only failure.** Per `PatternsReactRouter`'s own docs: "Nothing catches this before runtime — type checking and bundling both pass, because neither renders the page." `tsc` and `wix build` will not catch a missing `location` — only opening the page in a browser will. This is exactly why [Step 5's Preview](../../SKILL.md#validation) is not optional for Case B/D.
42
-
43
- ## 2. App shell — provider, router, routes
44
-
45
- ```tsx
46
- // {Feature}App.tsx — Case A, B or D
47
- import { withDashboard } from '@wix/patterns';
48
- import { WixPatternsProvider } from '@wix/patterns/provider';
49
- import { PatternsReactRouter, PatternsReactRoute } from '@wix/patterns/router';
50
- import { {Feature}CollectionPage } from './{Feature}CollectionPage';
51
- import { {Feature}EntityPage } from './{Feature}EntityPage';
52
- // Case D only:
53
- import { {Feature}SettingsPage } from './{Feature}SettingsPage';
54
-
55
- export const {Feature}App = withDashboard(() => (
56
- <WixPatternsProvider>
57
- <PatternsReactRouter>
58
- <PatternsReactRoute type="collection" path="/" element={<{Feature}CollectionPage />} />
59
- {/* Case B/D — editable record. Case A registers this ONE route instead, with
60
- {Feature}DetailPage as the element and no /new route (§4). Either way the
61
- type is `editEntity`: it wires back-navigation to the collection. */}
62
- <PatternsReactRoute type="editEntity" path="/:id" element={<{Feature}EntityPage />} />
63
- {/* Case B/D only — Case A has nothing to create: */}
64
- <PatternsReactRoute type="createEntity" path="/new" element={<{Feature}EntityPage />} />
65
- {/* Case D only: */}
66
- <PatternsReactRoute type="other" path="/settings" element={<{Feature}SettingsPage />} />
67
- </PatternsReactRouter>
68
- </WixPatternsProvider>
69
- ));
70
- ```
71
-
72
- `PatternsReactRoute`'s `type` is one of exactly `"collection" | "createEntity" | "editEntity" | "other"` — no dedicated settings value, so a settings route is `"other"`. Case B: delete the `/settings` route and the import above it — nothing else changes.
73
-
74
- `{Feature}CollectionPage` is [DRAFT_TEMPLATE_COLLECTION.md](DRAFT_TEMPLATE_COLLECTION.md)'s component, unchanged; `{Feature}SettingsPage` (Case D) is [DRAFT_TEMPLATE_SETTINGS.md](DRAFT_TEMPLATE_SETTINGS.md).
75
-
76
- ## 2b. The collection side of the handoff
77
-
78
- The router file above registers `/new`; something has to navigate there. All three of these live on
79
- the collection page, and `usePatternsNavigate` comes from **`@wix/patterns/router`** — not the root
80
- export, which is where it is easy to reach for it:
81
-
82
- ```tsx
83
- import { PrimaryPageButton } from '@wix/patterns';
84
- import { usePatternsNavigate } from '@wix/patterns/router';
85
-
86
- const { navigateToEntityPage } = usePatternsNavigate<{Entity}>();
87
- const openNew = () => navigateToEntityPage({ path: '/new' }); // no record yet — omit `entity`
88
-
89
- // CollectionPage.Header — primaryAction takes an ELEMENT, not a { text, onClick } config:
90
- <CollectionPage.Header
91
- title={{ text: '{Page Title}' }}
92
- primaryAction={<PrimaryPageButton text="Add {entity}" onClick={openNew} />}
93
- />
94
-
95
- // the empty state should offer the same action, and this one IS a config object:
96
- <CollectionEmptyState title="No {feature} yet" addNewCta={{ text: 'Add {entity}', onClick: openNew }} />
97
-
98
- // and a row opens the edit route:
99
- onRowClick={(item) => navigateToEntityPage({ path: `/${item.id}`, entity: item })}
100
- ```
101
-
102
- The two shapes differ on purpose — `primaryAction` is an element, `addNewCta` is `{ text, onClick }`.
103
- Guessing either costs a compile round.
104
-
105
- ## 3. Entity page — one component for both `/new` and `/:id`
106
-
107
- Full call details (both generics, what `onSave` receives, the `UseEntityPageParams` pick list) are in `<pkgRoot>/dist/docs/useEntityPage.md` — read it before filling in fields. The part specific to this router-based shape:
108
-
109
- ```tsx
110
- // {Feature}EntityPage.tsx — Case B or D (sketch — see dist/docs/useEntityPage.md for the full call)
111
- import { useParams } from 'react-router-dom'; // NOT @wix/patterns/router — PatternsReactRoute wraps react-router-dom's Route, but only exports PatternsReactRoute/PatternsReactRouter/usePatternsNavigate itself
112
- import { useEntityPage, EntityPage } from '@wix/patterns';
113
- import { useForm } from '@wix/patterns/form';
114
- import { fetch{Entity}, save{Entity}, type {Entity} } from './{feature}-api';
115
-
116
- // The form's shape is yours to declare, and need not match the saved entity type.
117
- type {Entity}FormFields = { name: string };
118
-
119
- export const {Feature}EntityPage = () => {
120
- const { id } = useParams<{ id?: string }>();
121
- const form = useForm<{Entity}FormFields>();
122
-
123
- const state = useEntityPage<{Entity}, {Entity}FormFields>({
124
- parentPath: '/', // NOT parentPageId — this shape always uses Patterns Router
125
- isNewEntity: () => !id, // a getter: the route can change (/new -> /:id after save) while this stays mounted
126
- form,
127
- fetch: () => (id ? fetch{Entity}(id).then((entity) => ({ entity })) : Promise.resolve({ entity: undefined })),
128
- onSave: ({ widgetsFormData }) =>
129
- save{Entity}({ id, ...form.getValues(), ...widgetsFormData }).then((updatedEntity) => ({ updatedEntity })),
130
- });
131
-
132
- return (
133
- <EntityPage state={state}>
134
- <EntityPage.Header title={{ text: id ? 'Edit {Entity}' : 'New {Entity}' }} />
135
- <EntityPage.Content>
136
- <EntityPage.MainContent>{/* form cards — see dist/docs/EntityPage.md */}</EntityPage.MainContent>
137
- </EntityPage.Content>
138
- </EntityPage>
139
- );
140
- };
141
- ```
142
-
143
- `useEntityPage`'s own docs are explicit about both details above: `parentPath` "Must be passed if using Patterns Router" (`parentPageId` is the non-router alternative — irrelevant here, since Case B/D always uses the router), and `isNewEntity` should be "a getter when the route can change while the page stays mounted" — exactly this component's case, since a successful create typically navigates `/new` → `/:newId`.
144
-
145
- **`UseEntityPageParams` is a `Pick<>`, so a param missing from it is a compile error, not an ignored prop.** `isNewEntity` is in that list at 1.470.0 and absent before ~1.46x. If it doesn't compile, read the pick list in your installed `dist/types/hooks/useEntityPage.d.ts` and upgrade — deleting the line makes a create route behave as an edit.
146
-
147
- ## 4. Read-only detail route — Case A
148
-
149
- A display-only collection still routes its rows to a page — but not an `EntityPage`, which has no
150
- read-only mode and still has none at **1.471.0**: `fetch` and `onSave` are both required, and
151
- `actionsBarConfig` (`saveCta.text`, `cancelCta`) can retext Save but not remove it. It would ship
152
- two buttons that either do nothing or save a form nobody was offered.
153
-
154
- Use a WDS `Page` — what Cairo does itself: `example-bm`'s `DataExtensionEntityViewPage` and
155
- auto-patterns' `ViewModeEntityPage` are both plain WDS `Page`s, the latter unexported.
156
-
157
- ```tsx
158
- // {Feature}DetailPage.tsx — Case A
159
- import { useEffect, useState } from 'react';
160
- import { useParams } from 'react-router-dom';
161
- import { Card, Loader, Page, Text } from '@wix/design-system';
162
- import { usePatternsNavigate } from '@wix/patterns/router';
163
- import { fetch{Entity}, type {Entity} } from './{feature}-api';
164
-
165
- export const {Feature}DetailPage = () => {
166
- const { id } = useParams<{ id: string }>();
167
- const { navigateToCollectionPage } = usePatternsNavigate();
168
- const [entity, setEntity] = useState<{Entity} | undefined>();
169
-
170
- useEffect(() => {
171
- if (id) {
172
- fetch{Entity}(id).then(setEntity);
173
- }
174
- }, [id]);
175
-
176
- return (
177
- <Page>
178
- {/* The way back is the header's back button — a read-only page has no Cancel. */}
179
- <Page.Header
180
- title={entity?.name ?? '{Entity}'}
181
- showBackButton
182
- onBackClicked={() => navigateToCollectionPage({ path: '/' })}
183
- />
184
- <Page.Content>
185
- {entity ? (
186
- <Card>
187
- <Card.Header title="Details" />
188
- <Card.Divider />
189
- <Card.Content>
190
- <Text>{entity.name}</Text>
191
- </Card.Content>
192
- </Card>
193
- ) : (
194
- <Loader />
195
- )}
196
- </Page.Content>
197
- </Page>
198
- );
199
- };
200
- ```
201
-
202
- If the request later grows an edit form this becomes §3's `EntityPage`, route type and `onRowClick`
203
- unchanged — which is why Case A registers `editEntity`, not `other`.
@@ -1,44 +0,0 @@
1
- # Draft Template — Settings page (Cases C and D)
2
-
3
- > Pick your case in [DRAFT_TEMPLATE.md](DRAFT_TEMPLATE.md) first; this page covers Case C or D.
4
-
5
- ## The settings page
6
-
7
- No dedicated toolkit file exists for this yet (unlike Entity/Collection) — the shape, verified against `useSettingsPage.md`:
8
-
9
- ```tsx
10
- // {Feature}SettingsPage.tsx — Case C or D
11
- import { SettingsPage, useSettingsPage, useSettings } from '@wix/patterns';
12
- import { useForm } from '@wix/patterns/form';
13
- import { fetch{Feature}Settings, save{Feature}Settings, type {Feature}Settings } from './{feature}-api';
14
-
15
- // The form's shape is yours to declare, and need not match the saved settings type —
16
- // one field per control on the page.
17
- type {Feature}SettingsFormFields = { reminderHours: number; notifyStaff: boolean };
18
-
19
- export const {Feature}SettingsPage = () => {
20
- const form = useForm<{Feature}SettingsFormFields>();
21
-
22
- const state = useSettingsPage<{Feature}Settings, {Feature}SettingsFormFields>({
23
- form,
24
- fetch: () => fetch{Feature}Settings().then((settings) => ({ settings })),
25
- onSave: () => save{Feature}Settings(form.getValues()),
26
- onCancel: async () => form.reset(),
27
- saveSuccessToast: 'Settings saved',
28
- saveErrorToast: (err, { retry }) => ({ message: 'Failed to save settings', action: { text: 'Retry', onClick: retry } }),
29
- });
30
-
31
- const settings = useSettings<{Feature}Settings, {Feature}SettingsFormFields>(state);
32
-
33
- return (
34
- <SettingsPage state={state}>
35
- <SettingsPage.Header title={{ text: '{Settings Page Title}' }} />
36
- <SettingsPage.Content>
37
- <SettingsPage.MainContent>{/* form cards — same field-controller patterns as EntityPage */}</SettingsPage.MainContent>
38
- </SettingsPage.Content>
39
- </SettingsPage>
40
- );
41
- };
42
- ```
43
-
44
- `useSettingsPage`'s params are all required except `saveSuccessToast`/`saveErrorToast`: `form`, `fetch`, `onSave`, `onCancel`. There is no `parentPath`/`parentPageId` — a settings page isn't reached by drilling into a row, so it carries no back-navigation contract, and Case C needs no router at all to reach it (Section 1's entry renders it directly).
@@ -1,263 +0,0 @@
1
- ---
2
- name: "CMS Data Operations Extended"
3
- description: Additional CMS data operations including count, upsert (bulk save), and update by filter patterns.
4
- ---
5
- # CMS Data Operations Extended
6
-
7
- This recipe covers additional CMS data operations not included in the basic CRUD recipe.
8
-
9
- ## Prerequisites
10
-
11
- 1. Wix CMS enabled on the site
12
- 2. Collections created with data
13
- 3. API access with CMS permissions
14
-
15
- ## Required APIs
16
-
17
- - **Data Items API**: [REST](https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/introduction)
18
-
19
- ## Count Data Items
20
-
21
- Count items in a collection, optionally with filters.
22
-
23
- **Endpoint**: `POST /wix-data/v2/items/count`
24
-
25
- **Count All Items**:
26
- ```bash
27
- curl -X POST \
28
- 'https://www.wixapis.com/wix-data/v2/items/count' \
29
- -H 'Content-Type: application/json' \
30
- -H 'Authorization: <AUTH>' \
31
- -d '{
32
- "dataCollectionId": "Products"
33
- }'
34
- ```
35
-
36
- **Response**:
37
- ```json
38
- {
39
- "totalCount": 42
40
- }
41
- ```
42
-
43
- **Count with Filter**:
44
- ```bash
45
- curl -X POST \
46
- 'https://www.wixapis.com/wix-data/v2/items/count' \
47
- -H 'Content-Type: application/json' \
48
- -H 'Authorization: <AUTH>' \
49
- -d '{
50
- "dataCollectionId": "Products",
51
- "filter": {
52
- "inStock": true
53
- }
54
- }'
55
- ```
56
-
57
- **Count with Complex Filter**:
58
- ```json
59
- {
60
- "dataCollectionId": "Products",
61
- "filter": {
62
- "$and": [
63
- { "inStock": true },
64
- { "price": { "$gte": 50 } }
65
- ]
66
- }
67
- }
68
- ```
69
-
70
- ## Bulk Save (Upsert)
71
-
72
- Insert new items or update existing items in a single operation. This is useful for syncing data.
73
-
74
- **Endpoint**: `POST /wix-data/v2/bulk/items/save`
75
-
76
- **Request Body**:
77
- ```json
78
- {
79
- "dataCollectionId": "Products",
80
- "dataItems": [
81
- {
82
- "id": "existing-item-id",
83
- "data": {
84
- "title": "Updated Product",
85
- "price": 199.99,
86
- "inStock": true
87
- }
88
- },
89
- {
90
- "data": {
91
- "title": "New Product",
92
- "price": 79.99,
93
- "inStock": true
94
- }
95
- }
96
- ],
97
- "returnEntity": true
98
- }
99
- ```
100
-
101
- ### Bulk Save Behavior
102
-
103
- | Scenario | Action |
104
- |----------|--------|
105
- | No `id` provided | INSERT - Creates new item with generated ID |
106
- | `id` provided, doesn't exist | INSERT - Creates new item with provided ID |
107
- | `id` provided, exists | UPDATE - Replaces existing item |
108
-
109
- > **Warning**: When updating, the entire item is replaced. Include all fields you want to keep.
110
-
111
- ## Update by Filter Pattern
112
-
113
- Wix CMS doesn't have a direct "update by filter" API. Use this two-step pattern:
114
-
115
- ### 3.1: Query Items to Update
116
-
117
- ```bash
118
- curl -X POST \
119
- 'https://www.wixapis.com/wix-data/v2/items/query' \
120
- -H 'Content-Type: application/json' \
121
- -H 'Authorization: <AUTH>' \
122
- -d '{
123
- "dataCollectionId": "Products",
124
- "query": {
125
- "filter": {
126
- "category": "electronics"
127
- }
128
- }
129
- }'
130
- ```
131
-
132
- ### 3.2: Bulk Update Those Items
133
-
134
- > **Important**: Use `id` (not `_id`) at the element level. The `data` object should NOT contain `_id`.
135
-
136
- ```bash
137
- curl -X POST \
138
- 'https://www.wixapis.com/wix-data/v2/bulk/items/update' \
139
- -H 'Content-Type: application/json' \
140
- -H 'Authorization: <AUTH>' \
141
- -d '{
142
- "dataCollectionId": "Products",
143
- "dataItems": [
144
- {
145
- "id": "item-1-from-query",
146
- "data": {
147
- "title": "Updated Title 1",
148
- "price": 99.99,
149
- "onSale": true
150
- }
151
- },
152
- {
153
- "id": "item-2-from-query",
154
- "data": {
155
- "title": "Updated Title 2",
156
- "price": 149.99,
157
- "onSale": true
158
- }
159
- }
160
- ]
161
- }'
162
- ```
163
-
164
- ### Alternative: Bulk Patch (Partial Update)
165
-
166
- If you only want to update specific fields without replacing the entire item, use Bulk Patch:
167
-
168
- **Endpoint**: `POST /wix-data/v2/bulk/items/patch`
169
-
170
- > **Important**: This endpoint uses `patches` array with `fieldModifications`, NOT `dataItems`. Do not confuse with bulk update.
171
-
172
- ```bash
173
- curl -X POST \
174
- 'https://www.wixapis.com/wix-data/v2/bulk/items/patch' \
175
- -H 'Content-Type: application/json' \
176
- -H 'Authorization: <AUTH>' \
177
- -d '{
178
- "dataCollectionId": "Products",
179
- "patches": [
180
- {
181
- "dataItemId": "item-1",
182
- "fieldModifications": [
183
- {
184
- "fieldPath": "onSale",
185
- "action": "SET_FIELD",
186
- "setFieldOptions": {
187
- "value": true
188
- }
189
- }
190
- ]
191
- }
192
- ]
193
- }'
194
- ```
195
-
196
- > **Common error**: If you get `WDE0080: patches must not be empty`, you sent `dataItems` instead of `patches`. Use the format above.
197
-
198
- ## Truncate Collection
199
-
200
- Remove all items from a collection (dangerous operation).
201
-
202
- **Endpoint**: `POST /wix-data/v2/items/truncate`
203
-
204
- ```bash
205
- curl -X POST \
206
- 'https://www.wixapis.com/wix-data/v2/items/truncate' \
207
- -H 'Content-Type: application/json' \
208
- -H 'Authorization: <AUTH>' \
209
- -d '{
210
- "dataCollectionId": "TestCollection"
211
- }'
212
- ```
213
-
214
- > **Warning**: This permanently deletes ALL items in the collection. Use with extreme caution.
215
-
216
- ## Aggregate Data
217
-
218
- Perform calculations on collection data using a pipeline of sequential stages.
219
-
220
- **Endpoint**: `POST /wix-data/v2/items/aggregate-pipeline`
221
-
222
- **Count by Category**:
223
- ```bash
224
- curl -X POST \
225
- 'https://www.wixapis.com/wix-data/v2/items/aggregate-pipeline' \
226
- -H 'Content-Type: application/json' \
227
- -H 'Authorization: <AUTH>' \
228
- -d '{
229
- "dataCollectionId": "Products",
230
- "pipeline": {
231
- "stages": [
232
- {
233
- "group": {
234
- "groupIds": [
235
- {"key": "category", "expression": {"fieldPath": "category"}}
236
- ],
237
- "accumulators": [
238
- {
239
- "resultFieldName": "count",
240
- "sum": {"expression": {"numeric": 1}}
241
- }
242
- ]
243
- }
244
- }
245
- ]
246
- }
247
- }'
248
- ```
249
-
250
- ## Operation Comparison
251
-
252
- | Operation | Use Case | Behavior |
253
- |-----------|----------|----------|
254
- | **Bulk Insert** | Add new items only | Fails if ID exists |
255
- | **Bulk Update** | Update existing items | Fails if ID doesn't exist, replaces entire item |
256
- | **Bulk Save** | Upsert (insert or update) | Creates or updates based on ID |
257
- | **Bulk Patch** | Partial update | Only modifies specified fields |
258
-
259
- ## Related Documentation
260
-
261
- - [Data Items API Reference](https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/introduction)
262
- - [CMS Operations Best Practices](cms-data-items-crud.md)
263
- - [CMS Schema Management](cms-schema-management.md)
@@ -1,162 +0,0 @@
1
- ---
2
- name: "CMS References And Relationships"
3
- description: "Add, replace, or remove items from MULTI_REFERENCE fields. Use insert-references, replace-references, remove-references endpoints. Required for managing multi-reference relationships - these CANNOT be set via regular insert/update/patch operations. Also covers single references and querying with expanded references."
4
- ---
5
- # CMS References & Relationships
6
-
7
- > **Standard call shape (every curl below).** The `<AUTH>` placeholder is shorthand for `Authorization: Bearer <TOKEN>` only. Body-bearing requests also need `Content-Type: application/json`.
8
-
9
- This recipe covers linking CMS collections together using reference fields.
10
-
11
- ## Prerequisites
12
-
13
- 1. Wix CMS enabled on the site
14
- 2. At least two collections to link together
15
- 3. API access with CMS permissions
16
-
17
- ## Required APIs
18
-
19
- - **Collections API**: [REST](https://dev.wix.com/docs/api-reference/business-solutions/cms/collection-management/data-collections/introduction)
20
- - **Data Items API**: [REST](https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/introduction)
21
-
22
- ## Reference Types
23
-
24
- | Type | Field Type | Relationship | Example |
25
- |------|------------|--------------|---------|
26
- | Single Reference | `REFERENCE` | One-to-one, Many-to-one | Product → Category |
27
- | Multi-Reference | `MULTI_REFERENCE` | One-to-many, Many-to-many | Product → Tags |
28
-
29
- ## Add a Single Reference Field
30
-
31
- **Endpoint**: `POST /wix-data/v2/collections/create-field`
32
-
33
- ```bash
34
- curl -X POST \
35
- 'https://www.wixapis.com/wix-data/v2/collections/create-field' \
36
- -H 'Content-Type: application/json' \
37
- -H 'Authorization: <AUTH>' \
38
- -d '{
39
- "dataCollectionId": "Products",
40
- "field": {
41
- "key": "category",
42
- "displayName": "Category",
43
- "type": "REFERENCE",
44
- "typeMetadata": {
45
- "reference": {
46
- "referencedCollectionId": "Categories"
47
- }
48
- }
49
- }
50
- }'
51
- ```
52
-
53
- ## Add a Multi-Reference Field
54
-
55
- **Endpoint**: `POST /wix-data/v2/collections/create-field`
56
-
57
- ```bash
58
- curl -X POST \
59
- 'https://www.wixapis.com/wix-data/v2/collections/create-field' \
60
- -H 'Content-Type: application/json' \
61
- -H 'Authorization: <AUTH>' \
62
- -d '{
63
- "dataCollectionId": "Products",
64
- "field": {
65
- "key": "tags",
66
- "displayName": "Tags",
67
- "type": "MULTI_REFERENCE",
68
- "typeMetadata": {
69
- "multiReference": {
70
- "referencedCollectionId": "Tags",
71
- "referencingFieldKey": "products",
72
- "referencingDisplayName": "Products"
73
- }
74
- }
75
- }
76
- }'
77
- ```
78
-
79
- ## Insert Multi-Reference Links
80
-
81
- **Endpoint**: `POST /wix-data/v2/bulk/items/insert-references`
82
-
83
- ```json
84
- {
85
- "dataCollectionId": "Products",
86
- "dataItemReferences": [
87
- {
88
- "referringItemId": "product-item-id",
89
- "referringItemFieldName": "tags",
90
- "referencedItemId": "tag-1-item-id"
91
- },
92
- {
93
- "referringItemId": "product-item-id",
94
- "referringItemFieldName": "tags",
95
- "referencedItemId": "tag-2-item-id"
96
- }
97
- ],
98
- "returnEntity": true
99
- }
100
- ```
101
-
102
- ## Replace All References
103
-
104
- **Endpoint**: `POST /wix-data/v2/items/replace-references`
105
-
106
- ```json
107
- {
108
- "dataCollectionId": "Products",
109
- "referringItemId": "product-item-id",
110
- "referringItemFieldName": "tags",
111
- "newReferencedItemIds": ["new-tag-1-id", "new-tag-2-id", "new-tag-3-id"]
112
- }
113
- ```
114
-
115
- > **Note**: To remove all references, pass an empty array for `newReferencedItemIds`.
116
-
117
- ## Remove References (Bulk)
118
-
119
- **Endpoint**: `POST /wix-data/v2/bulk/items/remove-references`
120
-
121
- ```json
122
- {
123
- "dataCollectionId": "Products",
124
- "dataItemReferences": [
125
- {
126
- "referringItemId": "product-id-1",
127
- "referringItemFieldName": "tags",
128
- "referencedItemId": "tag-to-remove-id"
129
- }
130
- ]
131
- }
132
- ```
133
-
134
- ## Query with Referenced Items Expanded
135
-
136
- **Endpoint**: `POST /wix-data/v2/items/query`
137
-
138
- ```json
139
- {
140
- "dataCollectionId": "Products",
141
- "query": {
142
- "filter": {
143
- "inStock": true
144
- }
145
- },
146
- "includeReferencedItems": ["category", "tags"]
147
- }
148
- ```
149
-
150
- ## Reference Query Operators
151
-
152
- | Operator | Description | Example |
153
- |----------|-------------|---------|
154
- | `$eq` | Exact match (single reference) | `{ "category": "id" }` |
155
- | `$hasSome` | Has at least one of | `{ "tags": { "$hasSome": ["id1", "id2"] } }` |
156
- | `$hasAll` | Has all of | `{ "tags": { "$hasAll": ["id1", "id2"] } }` |
157
-
158
- ## Related Documentation
159
-
160
- - [Data Items API Reference](https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/introduction)
161
- - [Collections API Reference](https://dev.wix.com/docs/api-reference/business-solutions/cms/collection-management/data-collections/introduction)
162
- - [CMS Schema Management Recipe](cms-schema-management.md)