Setting the file. One moment.
Wix Cms · Wix Vibe Headless · wix/skills · Skills Docs
ContentsBack to the top of the page Wix Blog
Previous
Reference Wix Image
references/cms/app/rest/ wix-cms.js
JavaScript · 186 lines · 8 KB
* Data Item — every read helper returns the item's `data` payload:
14 * _id {string} — GUID (route key, itemId for get/update/remove),
15 * _createdDate, _updatedDate {string} — ISO 8601 (use { "$date": "..." } in filters),
16 * _owner {string}, ...fields — collection field values keyed by field key
17 * Full reference: https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/data-item-object.md
18 *
19 * FILTERS & SORT (Wix API Query Language):
20 * filter: { field: value } for equality; { field: { $op: value } } for operators:
21 * $eq $ne $gt $gte $lt $lte $in $nin $startsWith $exists $isEmpty $hasSome $hasAll
22 * Combine with $and / $or / $not. Dates: { "$date": "2026-05-05T00:00:00.000Z" }.
23 * sort: [{ fieldName: "publishDate", order: "DESC" }]
24 * Full reference: https://dev.wix.com/docs/api-reference/articles/work-with-wix-apis/data-retrieval/about-the-wix-api-query-language.md
25 */
26
27 /**
28 * Query one page of items from a collection.
29 * Reference: https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/query-data-items.md
30 *
31 * Pass `nextCursor` back as `cursor` to load the next page. Define `filter`/`sort`/`fields`
32 * on the FIRST request only — on cursor follow-ups Wix reuses the original query and
33 * ignores them (so this helper omits them when a cursor is supplied).
34 *
35 * @param {string} dataCollectionId Collection name (e.g. "Tutorials").
36 * @param {{
37 * filter?: object,
38 * sort?: Array<{ fieldName: string, order?: "ASC"|"DESC" }>,
39 * limit?: number,
40 * cursor?: string,
41 * fields?: string[],
42 * includeReferences?: Array<{ field: string, limit?: number }>
43 * }} [options]
44 * @returns {Promise<{ items: object[], nextCursor: string|null }>} items are `data` payloads (each includes `_id`).
45 */
46 export async function queryDataItems ( dataCollectionId , { filter , sort , limit = 100 , cursor , fields , includeReferences } = {}) {
47 const query = {
48 ... (cursor
49 ? {}
50 : {
51 ... (filter ? { filter } : {}),
52 ... (sort ? { sort } : {}),
53 ... (fields ? { fields } : {}),
54 }),
55 cursorPaging: cursor ? { limit, cursor } : { limit },
56 };
57 const res = await wixApiRequest ( "/wix-data/v2/items/query" , {
58 method: "POST" ,
59 body: {
60 dataCollectionId,
61 query,
62 ... (includeReferences ? { includeReferences } : {}),
63 },
64 });
65 return {
66 items: (res?.dataItems ?? []). map (( d ) => d.data),
67 nextCursor: res?.pagingMetadata?.cursors?.next ?? null ,
68 };
69 }
70
71 /**
72 * Get a single item by its `_id`. Returns the `data` payload, or null if not found
73 * (or not readable by an anonymous visitor — see the permissions note up top).
74 * Reference: https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/get-data-item.md
75 *
76 * @param {string} dataCollectionId
77 * @param {string} itemId The item's `_id`.
78 * @returns {Promise<object|null>}
79 */
80 export async function getDataItem ( dataCollectionId , itemId ) {
81 try {
82 const res = await wixApiRequest ( `/wix-data/v2/items/${ encodeURIComponent ( itemId ) }` , {
83 method: "GET" ,
84 query: { dataCollectionId },
85 });
86 return res?.dataItem?.data ?? null ;
87 } catch {
88 return null ;
89 }
90 }
91
92 /**
93 * Get the first item whose `fieldKey` equals `value`. Use for slug-style routing —
94 * Wix Data has no native get-by-slug, so detail pages keyed off a human-readable field
95 * (e.g. a "slug" or "handle" field) resolve through this. Returns the `data` payload or null.
96 * Built on Query Data Items: https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/query-data-items.md
97 *
98 * @param {string} dataCollectionId
99 * @param {string} fieldKey Field to match (e.g. "slug").
100 * @param {unknown} value Value to match.
101 * @returns {Promise<object|null>}
102 */
103 export async function getDataItemBy ( dataCollectionId , fieldKey , value ) {
104 const { items } = await queryDataItems (dataCollectionId, { filter: { [fieldKey]: value }, limit: 1 });
105 return items[ 0 ] ?? null ;
106 }
107
108 /**
109 * Count items in a collection matching an optional filter. Use for empty-state logic
110 * (0 → prompt the user to add items in their Wix dashboard) and result counts.
111 * Reference: https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/count-data-items.md
112 *
113 * @param {string} dataCollectionId
114 * @param {object} [filter] Same filter syntax as queryDataItems.
115 * @returns {Promise<number>}
116 */
117 export async function countDataItems ( dataCollectionId , filter ) {
118 const res = await wixApiRequest ( "/wix-data/v2/items/count" , {
119 method: "POST" ,
120 body: { dataCollectionId, ... (filter ? { filter } : {}) },
121 });
122 return res?.totalCount ?? 0 ;
123 }
124
125 /**
126 * Insert a new item (e.g. a public form submission). The collection's Insert permission
127 * must be "Anyone" for this to succeed as a visitor. Returns the inserted `data` payload
128 * (including the assigned `_id`). Throws on failure (e.g. permission denied, validation).
129 * Reference: https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/insert-data-item.md
130 *
131 * @param {string} dataCollectionId
132 * @param {object} data Field-keyed values, e.g. { name, email, message }. Omit `_id`
133 * to let Wix assign one; supply `_id` only for a custom GUID.
134 * @returns {Promise<object>} The inserted item's `data` payload.
135 */
136 export async function insertDataItem ( dataCollectionId , data ) {
137 const res = await wixApiRequest ( "/wix-data/v2/items" , {
138 method: "POST" ,
139 body: { dataCollectionId, dataItem: { data } },
140 });
141 const inserted = res?.dataItem?.data;
142 if ( ! inserted) throw new Error ( `Insert into "${ dataCollectionId }" failed (no item returned).` );
143 return inserted;
144 }
145
146 /**
147 * Update (REPLACE) an existing item by `_id`. Returns the updated `data` payload. Throws
148 * if the item doesn't exist or the visitor lacks Update permission (usually admin/author only).
149 * Reference: https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/update-data-item.md
150 *
151 * ⚠ This is a FULL REPLACE: the new `data` overwrites the whole item, and any field NOT
152 * included is dropped. To change a few fields, fetch the item first (getDataItem), spread
153 * it, then pass the merged object — or use Patch Data Item for a partial change:
154 * https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/patch-data-item.md
155 *
156 * @param {string} dataCollectionId
157 * @param {string} itemId The item's `_id`.
158 * @param {object} data The complete new field set.
159 * @returns {Promise<object>} The updated item's `data` payload.
160 */
161 export async function updateDataItem ( dataCollectionId , itemId , data ) {
162 const res = await wixApiRequest ( `/wix-data/v2/items/${ encodeURIComponent ( itemId ) }` , {
163 method: "PUT" ,
164 body: { dataCollectionId, dataItem: { id: itemId, data: { ... data, _id: itemId } } },
165 });
166 const updated = res?.dataItem?.data;
167 if ( ! updated) throw new Error ( `Update of "${ itemId }" in "${ dataCollectionId }" failed (no item returned).` );
168 return updated;
169 }
170
171 /**
172 * Remove an item by `_id`. Irreversible. Returns the removed `data` payload. Throws if the
173 * visitor lacks Delete permission (usually admin/author only).
174 * Reference: https://dev.wix.com/docs/api-reference/business-solutions/cms/data-items/remove-data-item.md
175 *
176 * @param {string} dataCollectionId
177 * @param {string} itemId The item's `_id`.
178 * @returns {Promise<object|null>} The removed item's `data` payload.
179 */
180 export async function removeDataItem ( dataCollectionId , itemId ) {
181 const res = await wixApiRequest ( `/wix-data/v2/items/${ encodeURIComponent ( itemId ) }` , {
182 method: "DELETE" ,
183 query: { dataCollectionId },
184 });
185 return res?.dataItem?.data ?? null ;
186 }