@wix/agent-skills 1.16.2 → 1.17.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.
- package/package.json +1 -1
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +134 -120
- package/skills/wix-app/references/EMBEDDED_SCRIPT.md +6 -0
- package/skills/wix-app/references/SITE_PLUGIN.md +2 -2
- package/skills/wix-app/references/backend-event/COMMON-EVENTS.md +2 -2
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +182 -99
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +92 -47
- package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +15 -6
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +275 -0
- package/skills/wix-app/references/editor-react-component/COMPONENT-PREVIEW.md +29 -42
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +153 -449
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +66 -19
- package/skills/wix-app/references/editor-react-component/DIRECTIONALITY.md +53 -158
- package/skills/wix-app/references/editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md +78 -0
- package/skills/wix-app/references/editor-react-component/FUNCTION-HANDLERS.md +42 -134
- package/skills/wix-app/references/editor-react-component/MANIFEST-ERRORS.md +27 -0
- package/skills/wix-app/references/editor-react-component/PARTS.md +45 -24
- package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +63 -179
- package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +79 -163
- package/skills/wix-app/references/editor-react-component/SITE-CONTEXT-HOOKS.md +36 -21
- package/skills/wix-app/references/editor-react-component/SSR.md +30 -99
- package/skills/wix-base44-connector/SKILL.md +34 -17
- package/skills/wix-base44-connector/scripts/utils.js +33 -25
- package/skills/wix-headless/entry/bootstrap.mjs +9 -2
- package/skills/wix-headless/references/SDK_HANDOFF.md +1 -1
- package/skills/wix-headless/references/inline-recipes/how-to-code-a-store.md +42 -23
- package/skills/wix-headless/references/inline-recipes/how-to-code-pricing-plans.md +10 -8
- package/skills/wix-headless/references/inline-recipes/how-to-code-restaurant-orders.md +27 -24
- package/skills/wix-headless/references/managed/AUTHENTICATION.md +5 -0
- package/skills/wix-manage/SKILL.md +14 -2
- package/skills/wix-manage/references/bookings/booking-system-integration-gaps.md +20 -13
- package/skills/wix-manage/references/bookings/create-class-service.md +1 -1
- package/skills/wix-manage/references/bookings/end-to-end-booking-flow.md +24 -11
- package/skills/wix-manage/references/cms/cms-ecommerce-catalog-integration.md +5 -5
- package/skills/wix-manage/references/rich-content/author-ricos-rich-content.md +182 -5
- package/skills/wix-manage/references/seo/manage-seo-tags.md +315 -0
- package/skills/wix-manage/references/seo/manage-url-redirects.md +250 -0
- package/skills/wix-manage/references/sites/query-sites.md +72 -161
- package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +5 -6
- package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +13 -9
- package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +10 -7
- package/skills/wix-vibe-headless/platforms/base44.md +13 -10
- package/skills/wix-vibe-headless/references/bookings/INSTRUCTIONS.md +2 -0
- package/skills/wix-vibe-headless/references/bookings/app/rest/wix-bookings-checkout.js +9 -8
- package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +4 -1
- package/skills/wix-vibe-headless/references/restaurants/app/components/OrderCartDrawer.jsx +23 -11
- package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +1 -1
- package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +29 -31
- package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +15 -8
- package/skills/wix-vibe-headless/references/storefront/app/components/CartDrawer.jsx +37 -38
- package/skills/wix-vibe-headless/references/storefront/app/context/CartContext.jsx +2 -2
- package/skills/wix-vibe-headless/references/storefront/app/rest/wix-store-cart.js +35 -35
- package/skills/wix-app/references/editor-react-component/A11Y-REVIEW-REFERENCE.md +0 -172
- package/skills/wix-app/references/editor-react-component/A11Y-REVIEW.md +0 -143
- package/skills/wix-app/references/editor-react-component/COMPONENT-API.md +0 -484
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONFIGURATION.md +0 -225
- package/skills/wix-app/references/editor-react-component/EDIT-FLOW.md +0 -6
- package/skills/wix-app/references/editor-react-component/REACT-PATTERNS.md +0 -95
|
@@ -51,7 +51,7 @@ The Wix Bookings system contains **fundamental undocumented integration patterns
|
|
|
51
51
|
- ❌ **NOT** documented booking status vs order status separation
|
|
52
52
|
- ❌ **NOT** documented service properties preservation in checkout
|
|
53
53
|
- ❌ **NO** mention of `BACKOFFICE_MERCHANT` channel requirement
|
|
54
|
-
- ❌ **NO** explanation of why
|
|
54
|
+
- ❌ **NO** explanation of why the cart/order APIs are needed for bookings
|
|
55
55
|
|
|
56
56
|
**Additional Service-Specific Gaps**:
|
|
57
57
|
- ❌ **Courses**: Dual API requirement (booking + calendar events) completely undocumented
|
|
@@ -69,7 +69,7 @@ The Wix Bookings system contains **fundamental undocumented integration patterns
|
|
|
69
69
|
- Create booking → Booking system creates reservation only
|
|
70
70
|
- Use booking ID as catalog item in ecom system
|
|
71
71
|
- Ecom system handles all pricing, tax, discount calculations
|
|
72
|
-
- Create
|
|
72
|
+
- Create a cart and place the order for actual payment processing
|
|
73
73
|
- Async messaging system handles payment confirmation
|
|
74
74
|
- Booking status (CONFIRMED) independent of payment status
|
|
75
75
|
|
|
@@ -125,7 +125,7 @@ Actual Required Flow: Booking API → Ecom Integration → Payment ✓
|
|
|
125
125
|
|
|
126
126
|
**Universal Pattern** (Works for ALL Service Types):
|
|
127
127
|
```
|
|
128
|
-
Create Booking → Extract Booking ID → Use as Catalog Item ID → Create
|
|
128
|
+
Create Booking → Extract Booking ID → Use as Catalog Item ID → Create Cart → Place Order → Process Payment
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
### 2. Identify Service Type-Specific Booking Patterns
|
|
@@ -266,26 +266,33 @@ Create calendar events using `POST https://www.wixapis.com/calendar/v3/bulk/even
|
|
|
266
266
|
|
|
267
267
|
**MAJOR DISCOVERY**: ALL booking payments use identical ecommerce integration pattern.
|
|
268
268
|
|
|
269
|
-
**Step 6A: Create
|
|
269
|
+
**Step 6A: Create Cart with Booking ID as Catalog Item**
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
Cart V2 unifies cart and checkout — there is no separate checkout entity, so the created cart's `id` is what later steps use as the cart/checkout id.
|
|
272
|
+
|
|
273
|
+
**Endpoint**: `POST https://www.wixapis.com/ecom/v2/carts` ([REST](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart-v2/create-cart))
|
|
272
274
|
|
|
273
275
|
```json
|
|
274
276
|
{
|
|
275
|
-
"
|
|
277
|
+
"catalogItems": [{
|
|
276
278
|
"catalogReference": {
|
|
277
279
|
"catalogItemId": "<BOOKING_ID>",
|
|
278
280
|
"appId": "13d21c63-b5ec-5912-8397-c3a5ddb27a97"
|
|
279
281
|
},
|
|
280
282
|
"quantity": 1
|
|
281
|
-
}]
|
|
282
|
-
"channelType": "WEB"
|
|
283
|
+
}]
|
|
283
284
|
}
|
|
284
285
|
```
|
|
285
286
|
|
|
286
|
-
**Step 6B:
|
|
287
|
+
**Step 6B: Place Order for Payment Processing**
|
|
288
|
+
|
|
289
|
+
First calculate the cart to obtain a price-verification token:
|
|
290
|
+
|
|
291
|
+
**Endpoint**: `POST https://www.wixapis.com/ecom/v2/carts/{cartId}/calculate` — read `summary.priceVerificationToken` from the response.
|
|
292
|
+
|
|
293
|
+
Then place the order, passing that token:
|
|
287
294
|
|
|
288
|
-
**Endpoint**: `POST https://www.wixapis.com/ecom/
|
|
295
|
+
**Endpoint**: `POST https://www.wixapis.com/ecom/v2/carts/{cartId}/place-order` (body `{ "priceVerificationToken": "<TOKEN>" }`)
|
|
289
296
|
|
|
290
297
|
**Critical Architecture Discoveries**:
|
|
291
298
|
- **Automatic ID Transformation**: Booking IDs automatically valid as catalog item IDs
|
|
@@ -297,7 +304,7 @@ Create calendar events using `POST https://www.wixapis.com/calendar/v3/bulk/even
|
|
|
297
304
|
|
|
298
305
|
**Payment Processing Architecture**:
|
|
299
306
|
```
|
|
300
|
-
Booking (CONFIRMED) →
|
|
307
|
+
Booking (CONFIRMED) → Cart → Place Order → Payment Processing (async)
|
|
301
308
|
↓
|
|
302
309
|
Messaging System
|
|
303
310
|
↓
|
|
@@ -322,7 +329,7 @@ Booking (CONFIRMED) → Checkout → Order → Payment Processing (async)
|
|
|
322
329
|
**Service Packages**: Multi-service booking + ecom integration
|
|
323
330
|
|
|
324
331
|
**Universal Integration Considerations**:
|
|
325
|
-
- All service types use same
|
|
332
|
+
- All service types use the same cart/order creation pattern
|
|
326
333
|
- Pricing calculations always handled by ecom system
|
|
327
334
|
- Async payment confirmation applies to all booking types
|
|
328
335
|
- Service properties preserved across all integration points
|
|
@@ -406,7 +413,7 @@ Booking (CONFIRMED) → Checkout → Order → Payment Processing (async)
|
|
|
406
413
|
* [Standard Booking Flow](https://dev.wix.com/docs/api-reference/business-solutions/bookings/flow-single-service-booking) - Missing payment integration
|
|
407
414
|
* [Create Booking](https://dev.wix.com/docs/api-reference/business-solutions/bookings/bookings/bookings-writer-v2/create-booking) - No payment processing guidance
|
|
408
415
|
* [Service Types](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/about-service-types) - Missing integration patterns
|
|
409
|
-
* [Ecommerce
|
|
416
|
+
* [Ecommerce Cart](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart-v2/introduction) - No booking integration mention
|
|
410
417
|
|
|
411
418
|
**Completely Undocumented**:
|
|
412
419
|
* **Booking→Ecom Integration**: Universal pattern affecting all booking payments
|
|
@@ -149,7 +149,7 @@ curl -X POST 'https://www.wixapis.com/bookings/v2/bulk/services/create' \
|
|
|
149
149
|
- `defaultCapacity` is **required** — sets max participants per session
|
|
150
150
|
- After creation, class sessions must be scheduled separately via `bulkCreateEvents` using the returned `service.schedule.id` (see [Create and Update Booking Services](./create-and-update-booking-services.md))
|
|
151
151
|
|
|
152
|
-
Save the
|
|
152
|
+
**Response:** Save the service ID from `results[0].itemMetadata.id`
|
|
153
153
|
|
|
154
154
|
---
|
|
155
155
|
|
|
@@ -19,7 +19,7 @@ Step-by-step flow for implementing a complete booking experience using REST APIs
|
|
|
19
19
|
- **Services API**: [Query Services](https://dev.wix.com/docs/api-reference/business-solutions/bookings/services/services-v2/query-services)
|
|
20
20
|
- **Time Slots V2 API**: [List Availability Time Slots](https://dev.wix.com/docs/api-reference/business-solutions/bookings/time-slots/time-slots-v2/list-availability-time-slots)
|
|
21
21
|
- **Bookings API**: [Create Booking](https://dev.wix.com/docs/api-reference/business-solutions/bookings/bookings/bookings-writer-v2/create-booking), [Confirm Booking](https://dev.wix.com/docs/api-reference/business-solutions/bookings/bookings/bookings-writer-v2/confirm-booking)
|
|
22
|
-
- **eCommerce API**: [Create
|
|
22
|
+
- **eCommerce API**: [Create Cart](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart-v2/create-cart)
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
@@ -226,15 +226,17 @@ Use the `id` and `revision` from the Create Booking response. Set `paymentStatus
|
|
|
226
226
|
|
|
227
227
|
**Result**: Booking status changes to `CONFIRMED` and is visible in the booking calendar.
|
|
228
228
|
|
|
229
|
-
### For online payments: Create
|
|
229
|
+
### For online payments: Create a cart
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
Cart V2 unifies cart and checkout — there is no separate checkout entity. The created cart's `id` is what you use for the checkout URL and for placing the order.
|
|
232
232
|
|
|
233
|
-
**
|
|
233
|
+
**4a. Create Cart**
|
|
234
|
+
|
|
235
|
+
**Endpoint**: `POST https://www.wixapis.com/ecom/v2/carts`
|
|
234
236
|
|
|
235
237
|
```json
|
|
236
238
|
{
|
|
237
|
-
"
|
|
239
|
+
"catalogItems": [
|
|
238
240
|
{
|
|
239
241
|
"catalogReference": {
|
|
240
242
|
"catalogItemId": "<BOOKING_ID>",
|
|
@@ -242,22 +244,33 @@ Use the `id` and `revision` from the Create Booking response. Set `paymentStatus
|
|
|
242
244
|
},
|
|
243
245
|
"quantity": 1
|
|
244
246
|
}
|
|
245
|
-
]
|
|
246
|
-
"channelType": "WEB"
|
|
247
|
+
]
|
|
247
248
|
}
|
|
248
249
|
```
|
|
249
250
|
|
|
250
|
-
Use the booking ID as `catalogItemId` with the Wix Bookings app ID.
|
|
251
|
+
Use the booking ID as `catalogItemId` with the Wix Bookings app ID. Save `cart.id` from the response.
|
|
251
252
|
|
|
252
253
|
**4b. Get Checkout URL**
|
|
253
254
|
|
|
254
|
-
**Endpoint**: `POST https://www.wixapis.com/ecom/
|
|
255
|
+
**Endpoint**: `POST https://www.wixapis.com/ecom/v2/carts/{cartId}/get-checkout-url`
|
|
255
256
|
|
|
256
257
|
Redirect the user to the returned `checkoutUrl`. After payment, the booking is automatically confirmed.
|
|
257
258
|
|
|
258
|
-
**4c.
|
|
259
|
+
**4c. Place Order (alternative, server-to-server)**
|
|
260
|
+
|
|
261
|
+
First calculate the cart to get a price-verification token:
|
|
262
|
+
|
|
263
|
+
**Endpoint**: `POST https://www.wixapis.com/ecom/v2/carts/{cartId}/calculate`
|
|
264
|
+
|
|
265
|
+
Save `summary.priceVerificationToken` from the response, then place the order:
|
|
266
|
+
|
|
267
|
+
**Endpoint**: `POST https://www.wixapis.com/ecom/v2/carts/{cartId}/place-order`
|
|
259
268
|
|
|
260
|
-
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"priceVerificationToken": "<PRICE_VERIFICATION_TOKEN>"
|
|
272
|
+
}
|
|
273
|
+
```
|
|
261
274
|
|
|
262
275
|
Creates an order directly without redirect.
|
|
263
276
|
|
|
@@ -10,7 +10,7 @@ This recipe documents how to convert CMS collections into sellable product catal
|
|
|
10
10
|
|
|
11
11
|
Converting a CMS collection to a catalog enables:
|
|
12
12
|
- Items in the collection become purchasable products
|
|
13
|
-
- Integration with Wix Cart and
|
|
13
|
+
- Integration with the Wix Cart API (Cart V2, which unifies cart and checkout)
|
|
14
14
|
- Real-time price and availability from your CMS data
|
|
15
15
|
|
|
16
16
|
## Prerequisites
|
|
@@ -73,7 +73,7 @@ POST https://www.wixapis.com/wix-data/v2/collections/add-plugin
|
|
|
73
73
|
Most Wix sites with Stores, Bookings, or similar apps already have eCommerce installed. Check by querying the Cart API:
|
|
74
74
|
|
|
75
75
|
```
|
|
76
|
-
POST https://www.wixapis.com/ecom/
|
|
76
|
+
POST https://www.wixapis.com/ecom/v2/carts
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
## Step 3: Use Catalog Items in Cart
|
|
@@ -87,12 +87,12 @@ e593b0bd-b783-45b8-97c2-873d42aacaf4
|
|
|
87
87
|
### Add CMS Catalog Item to Cart
|
|
88
88
|
|
|
89
89
|
```
|
|
90
|
-
POST https://www.wixapis.com/ecom/
|
|
90
|
+
POST https://www.wixapis.com/ecom/v2/carts/{cartId}/add-line-items
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
```json
|
|
94
94
|
{
|
|
95
|
-
"
|
|
95
|
+
"catalogItems": [
|
|
96
96
|
{
|
|
97
97
|
"catalogReference": {
|
|
98
98
|
"appId": "e593b0bd-b783-45b8-97c2-873d42aacaf4",
|
|
@@ -133,4 +133,4 @@ CMS Catalogs are best for simple product catalogs. For complex eCommerce needs,
|
|
|
133
133
|
|
|
134
134
|
- [CMS Schema Management](cms-schema-management.md)
|
|
135
135
|
- [CMS Data Operations](cms-data-items-crud.md)
|
|
136
|
-
- [Wix Cart API](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart/
|
|
136
|
+
- [Wix Cart API](https://dev.wix.com/docs/api-reference/business-solutions/e-commerce/purchase-flow/cart-v2/introduction)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "Author Ricos Rich Content"
|
|
3
|
-
description:
|
|
3
|
+
description: Authoritative recipe for hand-authoring valid Ricos rich-content JSON (the richContent/nodes tree) used across Wix Blog posts, Stores product descriptions, Events, and CMS rich-text fields. Use whenever a user asks to create, output, or return Ricos, richContent, or nodes-tree JSON; retrieve and read this full recipe before API schema search or constructing the JSON. Covers paragraphs, headings, lists, blockquotes, dividers, tables, code blocks, images, buttons, audio, video, galleries, collapsible lists, HTML embeds, inline decorations, and nesting rules.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Author Ricos Rich Content
|
|
7
7
|
|
|
8
|
+
> **Routing rule (READ FIRST).** When hand-authoring or returning Ricos / `richContent` JSON, use **this recipe** — the shapes, nesting rules, spacer paragraphs, and plugin nodes below. Do not rely on API schema search alone; it misses those details. After this recipe loads, do not perform additional schema or documentation searches for node types covered here; compose and self-audit the JSON from this file. When the user only wants JSON output, **do not** call Ricos convert/validate APIs.
|
|
9
|
+
|
|
8
10
|
Ricos is Wix's rich-content format — a tree of typed nodes serialized as JSON. The same structure is embedded by many products: a Blog post's `draftPost.richContent`, a Store product's rich description, an Events description, and CMS rich-text fields all expect a Ricos document. This recipe is the **authoring reference for that node tree**: the valid shape of each node, how nodes nest, and how to format text. It is intentionally product-agnostic — the consuming API decides *where* the document goes; this recipe governs *what a valid document looks like*.
|
|
9
11
|
|
|
10
12
|
> A Ricos document is an object with a `nodes` array: `{ "nodes": [ /* block nodes */ ] }`. Whatever field the consuming API exposes (e.g. `richContent`), it holds this object. For validating or converting an existing document to/from HTML/Markdown, see [Ricos Converter Service](ricos-converter-service.md).
|
|
@@ -15,10 +17,58 @@ Ricos is Wix's rich-content format — a tree of typed nodes serialized as JSON.
|
|
|
15
17
|
- Every node carries a `type`, an optional `id`, and (for container nodes) a `nodes` array of children. Node `id`s are optional when authoring for a create request — the API generates them; the examples below omit `id` for brevity.
|
|
16
18
|
- **TEXT is a leaf.** A TEXT node only ever lives inside a `PARAGRAPH`, `HEADING`, or `CODE_BLOCK`. It must **never** sit directly in the root `nodes` array or inside a `LIST_ITEM`, `BLOCKQUOTE`, or `TABLE_CELL` — those must contain a `PARAGRAPH` (or `HEADING`) that then contains the TEXT. See [Nesting rules](#nesting-rules).
|
|
17
19
|
- Failing to wrap TEXT correctly produces the parse error **"Expected a paragraph node but found TEXT"**.
|
|
20
|
+
- **Block nodes do not get automatic vertical gap when rendered** — insert empty `PARAGRAPH` spacer nodes between sibling blocks when you need breathing room. See [Vertical spacing between blocks](#vertical-spacing-between-blocks).
|
|
21
|
+
|
|
22
|
+
## Required plugin shape checklist
|
|
23
|
+
|
|
24
|
+
Use this checklist while composing and again before returning JSON. Treat every path below as required for the described request:
|
|
25
|
+
|
|
26
|
+
- **Button CTA:** emit a root-level `BUTTON`, never a `PARAGRAPH` with an inline `LINK`. Include `buttonData.type: "LINK"`, `buttonData.text`, `buttonData.link.url`, `buttonData.link.target`, and `buttonData.containerData`.
|
|
27
|
+
- **Hosted audio:** emit `{ "type": "AUDIO", "nodes": [], "audioData": { ... } }`. The empty `nodes` array is on the AUDIO node beside `audioData` — never inside `audioData`. Include `audioData.containerData.alignment`, `width`, and `textWrap`, plus `audioData.audio.src.id`.
|
|
28
|
+
- **Video with thumbnail:** place `videoData.video.src` and `videoData.video.duration` inside `video`; place `videoData.thumbnail` beside `video`, with `src.id`, `width`, and `height`.
|
|
29
|
+
- **Gallery:** emit one root-level `GALLERY`. Put images in `galleryData.items`, not as child IMAGE nodes. Every item uses `image.media` with `src`, `width`, and `height`; include `galleryData.options.layout.type` and `numberOfColumns`.
|
|
30
|
+
- **Collapsible FAQ:** use `COLLAPSIBLE_LIST → COLLAPSIBLE_ITEM → COLLAPSIBLE_ITEM_TITLE | COLLAPSIBLE_ITEM_BODY → PARAGRAPH → TEXT`. Every PARAGRAPH includes `paragraphData`, and every item includes both title and body.
|
|
31
|
+
- **HTML embed:** emit a root-level `HTML` with `htmlData.source`, either `url` or `html`, and `htmlData.containerData.width`, `height`, and `alignment`.
|
|
32
|
+
|
|
33
|
+
## Vertical spacing between blocks
|
|
34
|
+
|
|
35
|
+
The renderer does **not** add margin between stacked block nodes. Adjacent paragraphs, headings, images, videos, tables, collapsible lists, buttons, galleries, and other blocks will sit flush against each other unless you separate them explicitly.
|
|
36
|
+
|
|
37
|
+
**Use an empty `PARAGRAPH` as a spacer** — a paragraph with no `nodes` (no TEXT children):
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{ "type": "PARAGRAPH" }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Place spacer paragraphs at the root `nodes` level (or inside a `CARD` page) wherever layout needs vertical rhythm:
|
|
44
|
+
|
|
45
|
+
- **After headings** — before the following body copy or media block.
|
|
46
|
+
- **Between paragraphs** — when two text blocks should not run together visually.
|
|
47
|
+
- **After block plugins** — images, videos, audio, galleries, tables, collapsible lists, HTML embeds, buttons, dividers, and lists often need a spacer before the **next distinct section** (not between every adjacent block in a minimal snippet the user enumerated).
|
|
48
|
+
- **After blockquotes** — only when the following block is a separate section; skip the spacer when the user asked for a blockquote immediately followed by a specific paragraph in one compact output.
|
|
49
|
+
- **Before major sections** — optional extra spacer when transitioning from one content group to another.
|
|
50
|
+
|
|
51
|
+
When the user requests **only** specific nodes in one JSON output (e.g. "a blockquote and then a paragraph"), include exactly those nodes — do not add spacer paragraphs they did not ask for.
|
|
52
|
+
|
|
53
|
+
Do **not** rely on `\n` inside `textData.text` for spacing — that does not create a real line break between blocks. Do **not** expect `paragraphData` margins or `containerData` alone to separate unrelated sibling nodes; the empty paragraph is the supported spacing mechanism.
|
|
54
|
+
|
|
55
|
+
**Example — spacer after an image and before a table:**
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"nodes": [
|
|
60
|
+
{ "type": "IMAGE", "imageData": { /* … */ } },
|
|
61
|
+
{ "type": "PARAGRAPH" },
|
|
62
|
+
{ "type": "TABLE", "nodes": [ /* … */ ], "tableData": { /* … */ } },
|
|
63
|
+
{ "type": "PARAGRAPH" },
|
|
64
|
+
{ "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Next section.", "decorations": [] } } ], "paragraphData": {} }
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
```
|
|
18
68
|
|
|
19
69
|
## Block node shapes
|
|
20
70
|
|
|
21
|
-
**PARAGRAPH** — the base text container. An empty paragraph — `{ "type": "PARAGRAPH" }` —
|
|
71
|
+
**PARAGRAPH** — the base text container. An empty paragraph — `{ "type": "PARAGRAPH" }` — is the **vertical spacer** between block nodes (the renderer adds no gap on its own). See [Vertical spacing between blocks](#vertical-spacing-between-blocks). `paragraphData.textStyle.textAlignment` accepts `AUTO`·`LEFT`·`CENTER`·`RIGHT`·`JUSTIFY`:
|
|
22
72
|
|
|
23
73
|
```json
|
|
24
74
|
{
|
|
@@ -142,6 +192,122 @@ Ricos is Wix's rich-content format — a tree of typed nodes serialized as JSON.
|
|
|
142
192
|
}
|
|
143
193
|
```
|
|
144
194
|
|
|
195
|
+
**BUTTON** — a standalone call-to-action block. **Not the same as an inline `LINK` decoration** on TEXT (that is hyperlinked body copy; this is a labeled button control). **`buttonData.type` is required** on every BUTTON node — use `"LINK"` for URL navigation or `"ACTION"` for viewer click handlers (never omit `type` even when `link` is present). Two `buttonData.type` values:
|
|
196
|
+
|
|
197
|
+
- **`LINK`** — navigates to a URL when clicked (`link.url`, `link.target`: `BLANK`·`SELF`, optional `link.rel`).
|
|
198
|
+
- **`ACTION`** — triggers a viewer `onClick` handler (store the node in JSON; behavior is configured in the Ricos viewer, not in the document body).
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"type": "BUTTON",
|
|
203
|
+
"buttonData": {
|
|
204
|
+
"type": "LINK",
|
|
205
|
+
"text": "Get Started",
|
|
206
|
+
"link": { "url": "https://example.com", "target": "BLANK", "rel": { "nofollow": true } },
|
|
207
|
+
"containerData": { "alignment": "CENTER", "width": { "size": "ORIGINAL" }, "textWrap": true },
|
|
208
|
+
"styles": { "borderRadius": 4, "borderWidth": 0, "backgroundColor": "#116DFF", "textColor": "#FFFFFF" }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**AUDIO** — uploaded audio via Wix Media `src.id`, or an embed variant whose `audioData.html` holds an iframe (SoundCloud, Spotify). Include `audioData.containerData` with `alignment` and width settings, and use an empty `nodes: []` array because AUDIO has no child nodes. Optional fields include `coverImage` (`src.id`, `width`, `height`), `name`, `authorName`, and `disableDownload`:
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"type": "AUDIO",
|
|
218
|
+
"nodes": [],
|
|
219
|
+
"audioData": {
|
|
220
|
+
"containerData": { "alignment": "CENTER", "width": { "size": "CONTENT" }, "textWrap": true },
|
|
221
|
+
"audio": { "src": { "id": "mp3/f0f74f_48772df0375c41cd88e8e29370ccf899" } },
|
|
222
|
+
"disableDownload": true,
|
|
223
|
+
"coverImage": { "src": { "id": "f0f74f_2973832f552e4002b58ec6abbe7fce71~mv2.png" }, "width": 436, "height": 524 },
|
|
224
|
+
"name": "Track title",
|
|
225
|
+
"authorName": "Artist name"
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**VIDEO** — Wix Media `video.src.id`, `duration` (seconds), and a `thumbnail` (`src.id`, `width`, `height`). YouTube and other embeds use the same `VIDEO` node shape with the appropriate media id:
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"type": "VIDEO",
|
|
235
|
+
"videoData": {
|
|
236
|
+
"containerData": { "width": { "size": "CONTENT" }, "alignment": "CENTER" },
|
|
237
|
+
"video": { "src": { "id": "video/11062b_a552731f40854d16a91627687fb8d1a6/1080p/mp4/file.mp4" }, "duration": 14.08 },
|
|
238
|
+
"thumbnail": { "src": { "id": "media/11062b_a552731f40854d16a91627687fb8d1a6f000.jpg" }, "width": 1920, "height": 1080 }
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**GALLERY** — multiple images in one block. Each `items[]` entry wraps `image.media` with `src` (`id` or `url`), `width`, and `height`. `galleryData.options` controls layout (`layout.type`: `GRID`, `numberOfColumns`, `orientation`; `item.ratio`, `item.crop`; `thumbnails.placement`):
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"type": "GALLERY",
|
|
248
|
+
"galleryData": {
|
|
249
|
+
"containerData": { "width": { "size": "CONTENT" }, "alignment": "CENTER", "textWrap": true },
|
|
250
|
+
"items": [
|
|
251
|
+
{ "image": { "media": { "src": { "id": "8bb438_36726a2d14ec44ee9edc5693bade1092.jpg" }, "width": 3648, "height": 5472 } } },
|
|
252
|
+
{ "image": { "media": { "src": { "id": "8bb438_6bbf8e82fe8f4b79b6e03ee79b66fd6a.jpg" }, "width": 1920, "height": 1280 } } }
|
|
253
|
+
],
|
|
254
|
+
"options": {
|
|
255
|
+
"layout": { "type": "GRID", "horizontalScroll": false, "orientation": "COLUMNS", "numberOfColumns": 3 },
|
|
256
|
+
"item": { "ratio": 1, "crop": "FILL" },
|
|
257
|
+
"thumbnails": { "placement": "NONE" }
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**COLLAPSIBLE_LIST** — FAQ-style expandable items. Nesting is `COLLAPSIBLE_LIST → COLLAPSIBLE_ITEM → COLLAPSIBLE_ITEM_TITLE | COLLAPSIBLE_ITEM_BODY → PARAGRAPH → TEXT` (body cells may also contain other supported block plugins such as IMAGE or VIDEO). The item wrapper type is **`COLLAPSIBLE_ITEM`** — not `COLLAPSIBLE_LIST_ITEM` or other variants:
|
|
264
|
+
|
|
265
|
+
```json
|
|
266
|
+
{
|
|
267
|
+
"type": "COLLAPSIBLE_LIST",
|
|
268
|
+
"nodes": [
|
|
269
|
+
{
|
|
270
|
+
"type": "COLLAPSIBLE_ITEM",
|
|
271
|
+
"nodes": [
|
|
272
|
+
{
|
|
273
|
+
"type": "COLLAPSIBLE_ITEM_TITLE",
|
|
274
|
+
"nodes": [
|
|
275
|
+
{ "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Question?", "decorations": [] } } ], "paragraphData": { "textStyle": { "textAlignment": "AUTO" } } }
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"type": "COLLAPSIBLE_ITEM_BODY",
|
|
280
|
+
"nodes": [
|
|
281
|
+
{ "type": "PARAGRAPH", "nodes": [ { "type": "TEXT", "textData": { "text": "Answer text.", "decorations": [] } } ], "paragraphData": { "textStyle": { "textAlignment": "AUTO" } } }
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
]
|
|
285
|
+
}
|
|
286
|
+
],
|
|
287
|
+
"collapsibleListData": {
|
|
288
|
+
"containerData": { "alignment": "CENTER", "textWrap": true },
|
|
289
|
+
"expandOnlyOne": false,
|
|
290
|
+
"initialExpandedItems": "FIRST",
|
|
291
|
+
"direction": "LTR"
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
`initialExpandedItems`: `NONE`·`FIRST`·`ALL`. Set `isQapageData: true` in list metadata when the list should render as FAQ structured data in search results.
|
|
297
|
+
|
|
298
|
+
**HTML** — embeds external content in an iframe. Provide either `url` (page URL) or inline `html` markup; `source` is typically `"HTML"`. Size via `containerData.width` / `height` (`custom` pixel strings or `size`):
|
|
299
|
+
|
|
300
|
+
```json
|
|
301
|
+
{
|
|
302
|
+
"type": "HTML",
|
|
303
|
+
"htmlData": {
|
|
304
|
+
"containerData": { "width": { "custom": "550" }, "height": { "custom": "550" }, "alignment": "CENTER" },
|
|
305
|
+
"url": "https://example.com/embed",
|
|
306
|
+
"source": "HTML"
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
145
311
|
## Inline text formatting (decorations)
|
|
146
312
|
|
|
147
313
|
Apply formatting with the `decorations` array on a TEXT node. Each decoration is an object with a `type` and (for some types) a data field:
|
|
@@ -169,6 +335,7 @@ Apply formatting with the `decorations` array on a TEXT node. Each decoration is
|
|
|
169
335
|
| `COLOR` | `colorData: { foreground: "#hex" }` (add `background` for highlight) |
|
|
170
336
|
| `LINK` | `linkData: { link: { url, target: "BLANK" } }` |
|
|
171
337
|
| `FONT_SIZE` | `fontSizeData: { unit: "PX", value: 24 }` |
|
|
338
|
+
| `SPOILER` | _(none — `{ "type": "SPOILER" }` hides text behind a reveal control)_ |
|
|
172
339
|
|
|
173
340
|
- **Mixed formatting in one paragraph → split into multiple TEXT nodes** (one per style run) inside the same PARAGRAPH. A single TEXT node carries one consistent set of decorations.
|
|
174
341
|
- Use a plain hex string in `foreground` for colors.
|
|
@@ -229,12 +396,16 @@ Note the mixed-run paragraph at the end: the linked words are their own TEXT nod
|
|
|
229
396
|
|
|
230
397
|
| Parent | Valid children |
|
|
231
398
|
| ------------------------------------ | ----------------------------------------------------------------------------------------------------- |
|
|
232
|
-
| Root `nodes` | PARAGRAPH, HEADING, BULLETED_LIST, ORDERED_LIST, BLOCKQUOTE, DIVIDER, IMAGE, TABLE, CODE_BLOCK
|
|
399
|
+
| Root `nodes` | PARAGRAPH, HEADING, BULLETED_LIST, ORDERED_LIST, BLOCKQUOTE, DIVIDER, IMAGE, TABLE, CODE_BLOCK, BUTTON, AUDIO, VIDEO, GALLERY, COLLAPSIBLE_LIST, HTML |
|
|
233
400
|
| PARAGRAPH / HEADING / CODE_BLOCK | TEXT |
|
|
234
401
|
| BULLETED_LIST / ORDERED_LIST | LIST_ITEM |
|
|
235
402
|
| LIST_ITEM / BLOCKQUOTE | PARAGRAPH (which then contains TEXT) |
|
|
236
403
|
| TABLE → TABLE_ROW → TABLE_CELL | cell contains PARAGRAPH / HEADING / IMAGE |
|
|
237
|
-
| IMAGE
|
|
404
|
+
| IMAGE / VIDEO | CAPTION (optional) |
|
|
405
|
+
| COLLAPSIBLE_LIST | COLLAPSIBLE_ITEM |
|
|
406
|
+
| COLLAPSIBLE_ITEM | COLLAPSIBLE_ITEM_TITLE, COLLAPSIBLE_ITEM_BODY |
|
|
407
|
+
| COLLAPSIBLE_ITEM_TITLE / _BODY | PARAGRAPH (and other plugins supported inside collapsible cells — see COLLAPSIBLE_LIST above) |
|
|
408
|
+
| BUTTON / AUDIO / GALLERY / HTML | _(leaf — `nodes: []` or omit)_ |
|
|
238
409
|
|
|
239
410
|
## Self-audit before returning the document
|
|
240
411
|
|
|
@@ -246,4 +417,10 @@ All decidable from the JSON itself — check before handing the document to a co
|
|
|
246
417
|
4. **Headings carry a `level`** (1–6) and nest logically (don't jump H2 → H4).
|
|
247
418
|
5. **No `\n` inside `textData.text`** — split into sibling nodes; mixed inline formatting → split into multiple TEXT runs.
|
|
248
419
|
6. **Images** use a Wix Media `id` (not a raw URL), with `width`, `height`, and meaningful `altText`.
|
|
249
|
-
7. **Links** — every `LINK` decoration has a valid `url` and `target`.
|
|
420
|
+
7. **Links** — every `LINK` decoration has a valid `url` and `target`. Use a `BUTTON` block with `buttonData.type: "LINK"` for CTAs — not an inline `LINK` decoration styled to look like a button.
|
|
421
|
+
8. **Buttons** — every BUTTON includes **`buttonData.type`** (`LINK` requires `link.url`; `ACTION` has no URL). Omitting `type` is invalid even when `link` is set. `LINK` buttons and inline `LINK` decorations serve different purposes.
|
|
422
|
+
9. **Media blocks** — AUDIO has root-level `nodes: []` and `audioData.containerData`; VIDEO keeps `thumbnail` beside `video` under `videoData`; every GALLERY item is under `galleryData.items` and carries `image.media.src`, `width`, and `height`.
|
|
423
|
+
10. **Collapsible lists** — every item has both `_TITLE` and `_BODY`, each wrapping content through `PARAGRAPH → TEXT`, and every PARAGRAPH has `paragraphData`.
|
|
424
|
+
11. **HTML embeds** — `htmlData` includes `source`, `containerData.width`, `containerData.height`, and either `url` or `html` (not both empty).
|
|
425
|
+
12. **Spoiler** — `SPOILER` is a decoration on `TEXT` (or `containerData.spoiler` on some block plugins in editor output); preserve it verbatim on edit.
|
|
426
|
+
13. **Vertical spacing** — stacked block nodes that should not appear cramped are separated by empty `{ "type": "PARAGRAPH" }` spacers — especially after images, videos, tables, collapsible lists, galleries, buttons, and between consecutive paragraphs. Missing spacers produce a wall-of-blocks layout with no renderer-added margin.
|