@wix/agent-skills 1.22.0 → 1.24.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/SKILL.md +12 -4
- package/skills/wix-app/references/APP_VALIDATION.md +16 -10
- package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +64 -50
- package/skills/wix-app/references/SDK_MODULE_MAP.md +2 -0
- package/skills/wix-app/references/dashboard-page/DRAFT_TEMPLATE.md +1 -1
- package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +4 -3
- package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +28 -25
- package/skills/wix-app/references/editor-react-component/BRANDED-COMPONENTS.md +8 -2
- package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +12 -14
- package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +4 -3
- package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +66 -9
- package/skills/wix-app/references/editor-react-component/EDITOR-EXTENSION-CONFIGURATION.md +25 -0
- package/skills/wix-app/references/editor-react-component/OVERFLOW.md +146 -0
- package/skills/wix-app/references/editor-react-component/PARTS.md +6 -0
- package/skills/wix-app/scripts/scan-a11y-eslint.cjs +25 -1
- package/skills/{wix-headless-fast → wix-headless-kit}/SKILL.md +96 -50
- package/skills/{wix-headless-fast → wix-headless-kit}/cold-start/bootstrap.mjs +2 -2
- package/skills/{wix-headless-fast → wix-headless-kit}/cold-start/cold-start.md +26 -31
- package/skills/wix-headless-kit/guides/capabilities.md +76 -0
- package/skills/{wix-headless-fast → wix-headless-kit}/guides/existing-site.md +3 -1
- package/skills/wix-headless-kit/guides/feedback.md +98 -0
- package/skills/wix-headless-kit/guides/migration.md +54 -0
- package/skills/{wix-headless-fast → wix-headless-kit}/guides/reference-mode.md +4 -1
- package/skills/{wix-headless-fast → wix-headless-kit}/install/AGENTS.md +6 -1
- package/skills/{wix-headless-fast → wix-headless-kit}/install/agents-md.mjs +5 -1
- package/skills/{wix-headless-fast → wix-headless-kit}/install/attach.mjs +14 -1
- package/skills/wix-headless-kit/install/check.mjs +87 -0
- package/skills/wix-headless-kit/install/context.mjs +169 -0
- package/skills/{wix-headless-fast → wix-headless-kit}/install/deploy.mjs +101 -23
- package/skills/{wix-headless-fast → wix-headless-kit}/install/setup.mjs +115 -41
- package/skills/{wix-headless-fast → wix-headless-kit}/install/templates.mjs +1 -1
- package/skills/wix-manage/SKILL.md +3 -3
- package/skills/wix-manage/references/app-installation/install-wix-apps.md +68 -2
- package/skills/wix-manage/references/cms/cms-dashboard-navigation.md +2 -2
- package/skills/wix-manage/references/cms/cms-data-items-crud.md +16 -16
- package/skills/wix-manage/references/cms/cms-publishing-flow.md +15 -15
- package/skills/wix-manage/references/cms/cms-schema-management.md +6 -6
- package/skills/wix-manage/references/contacts/bulk-label-and-unlabel-contacts.md +37 -4
- package/skills/wix-manage/references/ecommerce/ecom-pricing.md +29 -3
- package/skills/wix-manage/references/sites/query-sites.md +1 -8
- package/skills/wix-manage/references/sites/site-import.md +101 -37
- package/skills/wix-auth/SKILL.md +0 -12
- package/skills/wix-auth/references/device-flow.md +0 -140
- /package/skills/{wix-headless-fast → wix-headless-kit}/install/lock.mjs +0 -0
|
@@ -13,6 +13,7 @@ in the component's `.tsx` and `.module.css`.
|
|
|
13
13
|
- [Author CSS](#3-author-css)
|
|
14
14
|
- [Wire React](#4-wire-react)
|
|
15
15
|
- [Use Prop-Triggered States on the Root Only](#5-use-prop-triggered-states-on-the-root-only)
|
|
16
|
+
- [Expose Open/Collapsed Toggles](#6-expose-opencollapsed-toggles)
|
|
16
17
|
- [Checklist](#checklist)
|
|
17
18
|
|
|
18
19
|
## 1. Choose Supported States
|
|
@@ -24,6 +25,7 @@ in the component's `.tsx` and `.module.css`.
|
|
|
24
25
|
| Other interactive element whose editable focus appearance the user explicitly requests | `focus` |
|
|
25
26
|
| Disableable — `button`/`input`/`select`/`textarea`/`fieldset` or a disableable role | `disabled` (+ `invalid` for `input`/`select`/`textarea`) |
|
|
26
27
|
| Has a selectable/variant value in its data — `selected`/`active`/`current`/`open`/`expanded`/`checked`/`featured` | that custom state |
|
|
28
|
+
| Whole component opens/collapses (expandable panel, disclosure, dropdown, drawer), even when a click toggles it | root `isOpen` prop state — see §6 |
|
|
27
29
|
| None of the above | no states — resting style only |
|
|
28
30
|
|
|
29
31
|
An explicit `role` overrides the tag's implicit semantics: `<input role="button">`
|
|
@@ -51,7 +53,10 @@ nested (`card__row--selected`).
|
|
|
51
53
|
## 3. Author CSS
|
|
52
54
|
|
|
53
55
|
Put the resting value in the bare class; put only the state override in the
|
|
54
|
-
state selector.
|
|
56
|
+
state selector. When both set the same property, write the state selector
|
|
57
|
+
**before** the bare class. Manifest generation can otherwise record the state
|
|
58
|
+
value as the part's resting `defaultValue`, even though runtime CSS renders
|
|
59
|
+
correctly. The state selector still wins at runtime through its specificity.
|
|
55
60
|
|
|
56
61
|
- **Native design state** — pair the pseudo-class with the `:global` modifier.
|
|
57
62
|
Every exposed native state needs both selectors in the same rule; do not
|
|
@@ -63,17 +68,22 @@ state selector.
|
|
|
63
68
|
The bare selector is the short **module** class (`.cta`); the `:global(...)`
|
|
64
69
|
state class is the **prefixed** global one.
|
|
65
70
|
|
|
71
|
+
Check text contrast against every background it appears on, including resting,
|
|
72
|
+
hover, and selected states. Normal text needs at least 4.5:1; large text needs
|
|
73
|
+
3:1. Pale gray small text on white or a tinted selected row commonly fails.
|
|
74
|
+
The local static accessibility scan cannot measure rendered color contrast.
|
|
75
|
+
|
|
66
76
|
```css
|
|
77
|
+
.cta:global(.pricing-card-cta--hover),
|
|
78
|
+
.cta:hover {
|
|
79
|
+
background: #4f46e5;
|
|
80
|
+
}
|
|
67
81
|
.cta {
|
|
68
82
|
background: #6366f1;
|
|
69
83
|
font-family: 'Inter', sans-serif;
|
|
70
84
|
font-size: 14px;
|
|
71
85
|
color: #ffffff;
|
|
72
86
|
} /* resting */
|
|
73
|
-
.cta:global(.pricing-card-cta--hover),
|
|
74
|
-
.cta:hover {
|
|
75
|
-
background: #4f46e5;
|
|
76
|
-
}
|
|
77
87
|
.cta:global(.pricing-card-cta--disabled),
|
|
78
88
|
.cta:disabled {
|
|
79
89
|
opacity: 0.5;
|
|
@@ -91,7 +101,9 @@ state class is the **prefixed** global one.
|
|
|
91
101
|
- **Native** — render the correct interactive element (`<button>`, an
|
|
92
102
|
interactive `role`, or a handler). No custom state class is needed, but the
|
|
93
103
|
element must still satisfy the accessibility contract for its semantics.
|
|
94
|
-
- **Custom** — toggle the global state class from the element's data.
|
|
104
|
+
- **Custom** — toggle the global state class from the element's data. Every
|
|
105
|
+
state class toggled in TSX needs a matching `:global()` rule in §3; without
|
|
106
|
+
one the manifest generator silently drops the state.
|
|
95
107
|
- **Inner elements** — every named inner element gets an `elementProps` entry;
|
|
96
108
|
spread it so editor-driven states reach it. On a raw HTML element also merge
|
|
97
109
|
`elementProps?.<key>.className` inline; on a skill-built sub-component the
|
|
@@ -155,8 +167,9 @@ Rules:
|
|
|
155
167
|
`props: { isFeatured: true }` as the trigger.
|
|
156
168
|
- To give the state styling, pair the root's **module** class with a prefixed
|
|
157
169
|
`:global(.<component-name>--<state>)` rule. With a matching class the manifest
|
|
158
|
-
entry carries that `className
|
|
159
|
-
|
|
170
|
+
entry carries that `className` and the editor lists it with the design-panel
|
|
171
|
+
states; with none it is props-only and appears in the on-stage state picker,
|
|
172
|
+
which sets the prop. An open/collapsed toggle must stay props-only (§6).
|
|
160
173
|
|
|
161
174
|
```css
|
|
162
175
|
.pricingCard:global(.pricing-card--is-featured) {
|
|
@@ -166,7 +179,48 @@ Rules:
|
|
|
166
179
|
|
|
167
180
|
Prefer a native state (interactive markup) or a class trigger (per-item data
|
|
168
181
|
such as `row.selected`) whenever one fits — those are the common cases and work
|
|
169
|
-
at any depth. Reach for a prop trigger only for a root-level boolean switch
|
|
182
|
+
at any depth. Reach for a prop trigger only for a root-level boolean switch
|
|
183
|
+
or an open/collapsed toggle (§6).
|
|
184
|
+
|
|
185
|
+
## 6. Expose Open/Collapsed Toggles
|
|
186
|
+
|
|
187
|
+
For a component that opens or collapses, expose its state to the editor even
|
|
188
|
+
when a click toggles it. `useState` alone gives the manifest no state picker.
|
|
189
|
+
For one-of-many item bodies, use the active-item contract instead.
|
|
190
|
+
|
|
191
|
+
- Add `isOpen?: ElementState<boolean>` and set `isOpen: false` in
|
|
192
|
+
`defaultProps`.
|
|
193
|
+
- Seed and resync internal state from the prop; clicks update internal state.
|
|
194
|
+
- Always render the collapsible content; hide it with CSS plus `aria-hidden`
|
|
195
|
+
and `inert` when closed. Never mount it with `open && …`.
|
|
196
|
+
- Style the open state with inner-part classes
|
|
197
|
+
(`<component-name>-content--open`) and matching `:global()` rules, not only
|
|
198
|
+
inline styles or refs measured during render.
|
|
199
|
+
- Keep the root state props-only for the on-stage picker (§5).
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
const [open, setOpen] = React.useState(Boolean(isOpen));
|
|
203
|
+
React.useEffect(() => setOpen(Boolean(isOpen)), [isOpen]);
|
|
204
|
+
|
|
205
|
+
<div
|
|
206
|
+
{...elementProps?.content}
|
|
207
|
+
aria-hidden={!open}
|
|
208
|
+
{...(!open && { inert: '' })}
|
|
209
|
+
className={classNames(
|
|
210
|
+
'info-panel-content',
|
|
211
|
+
styles.content,
|
|
212
|
+
open && 'info-panel-content--open',
|
|
213
|
+
elementProps?.content?.className,
|
|
214
|
+
)}
|
|
215
|
+
>
|
|
216
|
+
<p>{text}</p>
|
|
217
|
+
</div>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
```css
|
|
221
|
+
.content { display: none; }
|
|
222
|
+
.content:global(.info-panel-content--open) { display: block; }
|
|
223
|
+
```
|
|
170
224
|
|
|
171
225
|
## Checklist
|
|
172
226
|
|
|
@@ -176,4 +230,7 @@ at any depth. Reach for a prop trigger only for a root-level boolean switch.
|
|
|
176
230
|
- [ ] Non-input controls retain a standalone `:focus-visible` keyboard indicator.
|
|
177
231
|
- [ ] Custom state classes are flat, global, and prefixed by component and part.
|
|
178
232
|
- [ ] Named inner parts spread and merge their `elementProps` entry.
|
|
233
|
+
- [ ] Every state class toggled in TSX has a matching `:global()` CSS rule.
|
|
179
234
|
- [ ] `ElementState<boolean>` is used only for a component-level root state.
|
|
235
|
+
- [ ] An open/collapsed component exposes a props-only `isOpen` root state,
|
|
236
|
+
syncs internal state from it, and always renders its content.
|
|
@@ -9,12 +9,17 @@ generation rewrites
|
|
|
9
9
|
For a new component, complete the scaffolded installation and layout fields.
|
|
10
10
|
For an existing component, change only the sizing, installation, or manifest
|
|
11
11
|
behavior requested by the user; preserve every other extension field.
|
|
12
|
+
Use the current scaffold's field shape and the values below. Inspect installed
|
|
13
|
+
`@wix/astro` or schema types only if a related typecheck or build error requires it.
|
|
14
|
+
Normal component setup needs no `ELEMENT_TYPE` or `DATA_TYPE` lookup: the
|
|
15
|
+
generated `editorElement` and props manifest supply those details.
|
|
12
16
|
|
|
13
17
|
## Contents
|
|
14
18
|
|
|
15
19
|
- [Preserve the Extension Shape](#preserve-the-extension-shape)
|
|
16
20
|
- [Choose Initial Height](#choose-initial-height)
|
|
17
21
|
- [Choose Resize Direction](#choose-resize-direction)
|
|
22
|
+
- [Values](#values)
|
|
18
23
|
- [Checklist](#checklist)
|
|
19
24
|
|
|
20
25
|
## Preserve the Extension Shape
|
|
@@ -53,6 +58,12 @@ should fit content, use `content`.
|
|
|
53
58
|
|
|
54
59
|
Allow an axis only when dragging it produces a meaningful result.
|
|
55
60
|
|
|
61
|
+
For each allowed axis, implement what happens when content no longer fits.
|
|
62
|
+
Content height must grow after wrapping or changing items. A bounded height
|
|
63
|
+
needs a fitting layout or a deliberate accessible scroll region. Installation
|
|
64
|
+
defaults alone do not prevent overflow after resizing. Do not rely on native
|
|
65
|
+
container overflow controls for a custom component's internal DOM.
|
|
66
|
+
|
|
56
67
|
| Value | Use when |
|
|
57
68
|
| --- | --- |
|
|
58
69
|
| `horizontalAndVertical` | Content meaningfully fills both axes; default for framed visuals and most layouts |
|
|
@@ -61,11 +72,25 @@ Allow an axis only when dragging it produces a meaningful result.
|
|
|
61
72
|
| `aspectRatio` | Distortion would break the component's identity |
|
|
62
73
|
| `none` | A parent fully owns size; do not use for a top-level component |
|
|
63
74
|
|
|
75
|
+
## Values
|
|
76
|
+
|
|
77
|
+
Every value the scaffold uses comes from `LAYOUT` in
|
|
78
|
+
`@wix/react-component-schema`; do not search `node_modules` for them.
|
|
79
|
+
|
|
80
|
+
| Field | Values |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `layout.resizeDirection` (`LAYOUT.RESIZE_DIRECTION`) | `horizontal`, `vertical`, `horizontalAndVertical`, `aspectRatio`, `none` |
|
|
83
|
+
| `layout.contentResizeDirection` (`LAYOUT.CONTENT_RESIZE_DIRECTION`) | `horizontal`, `vertical`, `horizontalAndVertical`, `none`: the axes along which content growth resizes the component |
|
|
84
|
+
| `initialSize.{width,height}.sizingType` (`LAYOUT.SIZING_TYPE`) | `content`, `pixels`, `stretched` |
|
|
85
|
+
| `installation.staticContainer` | `'HOMEPAGE'`, `'GLOBAL_PAGE'` |
|
|
86
|
+
|
|
64
87
|
Edit the scaffolded `layout`, `installation`, and `resources` fields in place;
|
|
65
88
|
do not reconstruct the extension from an example. For a new component, add
|
|
66
89
|
`staticContainer: 'HOMEPAGE'`. For an existing component, preserve its current
|
|
67
90
|
`staticContainer` value unless the request explicitly changes installation
|
|
68
91
|
behavior.
|
|
92
|
+
The scaffold's `installation` object accepts `staticContainer` next to
|
|
93
|
+
`initialSize`; add the literal above without searching `@wix/astro` types.
|
|
69
94
|
|
|
70
95
|
## Checklist
|
|
71
96
|
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Overflow and Resizing
|
|
2
|
+
|
|
3
|
+
Apply when creating a component or changing its layout, content, or sizing.
|
|
4
|
+
Custom components own their internal layout; do not assume the editor exposes
|
|
5
|
+
native-container overflow settings for their DOM. The component must keep
|
|
6
|
+
content and controls usable within its assigned size.
|
|
7
|
+
|
|
8
|
+
## Choose What Happens When Content Does Not Fit
|
|
9
|
+
|
|
10
|
+
- **Content-height component:** reflow at narrower widths and let normal-flow
|
|
11
|
+
content establish height. Do not constrain it with `height: 100%`, a fixed
|
|
12
|
+
height, or absolute positioning of all content.
|
|
13
|
+
- **Bounded-height component:** propagate the height constraint through growing
|
|
14
|
+
wrappers (`min-height: 0` for flex/grid items). Fit the content or give the
|
|
15
|
+
intended content region `overflow: auto`; keep essential controls reachable.
|
|
16
|
+
Choose scrolling only when it suits the requested interaction.
|
|
17
|
+
- **Carousel or other intentional overflow:** contain the oversized track in
|
|
18
|
+
its own viewport and provide working navigation/scrolling to every item.
|
|
19
|
+
Treat a requested count such as "show four items at a time" as the
|
|
20
|
+
default/initial-width presentation unless the user explicitly requires that
|
|
21
|
+
column count at every width. Each carousel page should still contain that
|
|
22
|
+
requested group at narrow widths, but its internal layout must reflow so every
|
|
23
|
+
required item is usable. Stacking or wrapping the current page's items
|
|
24
|
+
preserves the group; squeezing them into tiny columns or clipping later items
|
|
25
|
+
does not. Choose the installation width, gaps, padding, and usable item
|
|
26
|
+
minimum together so the requested count actually fits at the initial size.
|
|
27
|
+
|
|
28
|
+
A container-driven group page can preserve the requested grouping without
|
|
29
|
+
changing the carousel's item-count logic:
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
.trackViewport {
|
|
33
|
+
min-width: 0;
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.page {
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
display: grid;
|
|
40
|
+
flex: 0 0 100%;
|
|
41
|
+
min-width: 0;
|
|
42
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
|
|
43
|
+
gap: 16px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.item {
|
|
47
|
+
min-width: 0;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
At a wide initial width, the page uses the requested presentation count. When
|
|
52
|
+
the component is narrower than a usable item minimum, the same group wraps to
|
|
53
|
+
fewer columns or a single column and its content-height component grows.
|
|
54
|
+
Equivalent container-query or wrapping layouts are valid. A fixed
|
|
55
|
+
`repeat(<count>, minmax(0, 1fr))` or percentage basis derived from the count is
|
|
56
|
+
not sufficient as the only layout for a horizontally resizable component.
|
|
57
|
+
|
|
58
|
+
Do not apply blanket `overflow: hidden`/`clip` to the root or page as a repair.
|
|
59
|
+
It can hide text, focus indicators, navigation, and overlays while leaving the
|
|
60
|
+
layout defect intact. Clip a dedicated media/track/decorative region only when
|
|
61
|
+
that is its intended behavior. Preserve deliberate shadows and overlays.
|
|
62
|
+
|
|
63
|
+
## Remove Intrinsic Sizing Traps
|
|
64
|
+
|
|
65
|
+
`width: 100%` and `box-sizing: border-box` on the root are necessary, but do not
|
|
66
|
+
constrain descendants. A bare `1fr` track has an automatic minimum; three such
|
|
67
|
+
tracks can exceed the container even when the grid itself is correctly sized.
|
|
68
|
+
|
|
69
|
+
- Use `min-width: 0` on flex/grid items that must shrink, including nested
|
|
70
|
+
content wrappers. For a fixed column count, use `minmax(0, 1fr)`; still adapt
|
|
71
|
+
the layout when columns would become too narrow to use.
|
|
72
|
+
- Prefer fewer columns or wrapping to squeezing text and controls. An intrinsic
|
|
73
|
+
collection can use the following pattern; the minimum never exceeds its
|
|
74
|
+
container's content width:
|
|
75
|
+
|
|
76
|
+
```css
|
|
77
|
+
.grid {
|
|
78
|
+
box-sizing: border-box;
|
|
79
|
+
display: grid;
|
|
80
|
+
min-width: 0;
|
|
81
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
|
|
82
|
+
gap: 16px;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`minmax(280px, 1fr)` alone still overflows a slot narrower than 280px.
|
|
87
|
+
This grid is suitable for a wrapping collection, not a substitute for a
|
|
88
|
+
carousel's item/navigation contract.
|
|
89
|
+
- For user-authored prose, allow wrapping and use `overflow-wrap: anywhere`
|
|
90
|
+
where long words/URLs could force intrinsic width. Use truncation only when
|
|
91
|
+
the product intends it and essential content remains available.
|
|
92
|
+
- Constrain images/media to the space available; preserve aspect ratio or use
|
|
93
|
+
an intentional fitted media frame. Check fixed-size media plus adjacent text,
|
|
94
|
+
padding, borders, and gaps together.
|
|
95
|
+
- Let control rows and pagination adapt without losing buttons, focus rings,
|
|
96
|
+
or usable target sizes. `min-width: 0` does not make fixed children or large
|
|
97
|
+
padding fit by itself.
|
|
98
|
+
|
|
99
|
+
Adapt to the component's width, including a narrow slot on a desktop viewport.
|
|
100
|
+
Do not derive the layout from `window.innerWidth` or viewport breakpoints. If
|
|
101
|
+
container queries are needed, establish the query container on an appropriate
|
|
102
|
+
ancestor; a query cannot restyle its own container based on that container's
|
|
103
|
+
size. Do not add size containment on an auto-height component that prevents
|
|
104
|
+
content from establishing its height.
|
|
105
|
+
|
|
106
|
+
## Review Before Reporting Completion
|
|
107
|
+
|
|
108
|
+
First inspect the sizing chain in source. Identify the root, growing wrappers,
|
|
109
|
+
tracks, cards, text, media, and controls; check each constrained axis. Do not
|
|
110
|
+
infer safety from a CSS keyword or a successful build.
|
|
111
|
+
|
|
112
|
+
When a runnable browser preview is available, exercise the actual component:
|
|
113
|
+
|
|
114
|
+
1. Vary the **component container** independently of the page viewport. Cover
|
|
115
|
+
its initial size, 320px, a narrower stress probe such as 240px, and a wider
|
|
116
|
+
slot. For a vertically resizable component, also test a short bounded height;
|
|
117
|
+
for content height, verify the root grows without overlapping the next block.
|
|
118
|
+
A horizontally resizable top-level component must keep required content
|
|
119
|
+
usable at 320px unless an actual supported editor minimum is part of its
|
|
120
|
+
contract. Treat 240px as a stress probe. Report any unsupported size and its
|
|
121
|
+
remaining usability limit.
|
|
122
|
+
2. Use long prose and an unbroken token, larger text, changed padding/borders,
|
|
123
|
+
and representative item counts. For carousels, test navigation and the
|
|
124
|
+
longest item; include RTL when direction changes layout or navigation.
|
|
125
|
+
3. Compare root/region `scrollWidth` with `clientWidth` (allow about 1px for
|
|
126
|
+
rounding), and inspect descendant bounds. For bounded height, also compare
|
|
127
|
+
`scrollHeight` and `clientHeight`. An intentional scroll region/track may
|
|
128
|
+
exceed its client size, but its content must remain reachable and contained.
|
|
129
|
+
Check the component itself: a page ancestor may clip overflow while the
|
|
130
|
+
document has no horizontal scrollbar. Conversely, shadows/overlays do not
|
|
131
|
+
automatically mean the content layout is broken.
|
|
132
|
+
4. Visually inspect and use the controls/keyboard. Passing geometry checks by
|
|
133
|
+
clipping required content is a failure. Verify intentional scroll regions
|
|
134
|
+
are usable with keyboard and touch, focus stays visible, and navigation can
|
|
135
|
+
reach every item.
|
|
136
|
+
|
|
137
|
+
Fix confirmed component-owned defects and repeat affected cases. If the first
|
|
138
|
+
incorrect constraint comes from the host layout, report that boundary instead
|
|
139
|
+
of masking it inside the component. For existing components, preserve unrelated
|
|
140
|
+
public props, editor overrides, and behavior.
|
|
141
|
+
|
|
142
|
+
Report sizes/states tested and any remaining overflow or inaccessible content.
|
|
143
|
+
If no browser preview or fixture is available, perform the source review and
|
|
144
|
+
state that rendered resize behavior is **unverified**; do not claim the resize
|
|
145
|
+
review passed. Build, typecheck, a11y scans, and manifest generation do not
|
|
146
|
+
establish that layout fits.
|
|
@@ -45,6 +45,12 @@ Apply this filter to every candidate:
|
|
|
45
45
|
share the same semantic editor surface. Distinguish position with data or a
|
|
46
46
|
module-only helper class, not separate part names.
|
|
47
47
|
|
|
48
|
+
The manifest generator can silently omit a named part behind conditional JSX.
|
|
49
|
+
Keep an editor-controlled part mounted in the render it inspects. Hide it with
|
|
50
|
+
CSS driven by a data attribute, or disable it when it should remain visible.
|
|
51
|
+
After generating the manifest, confirm that its `elements` include every
|
|
52
|
+
intended named part.
|
|
53
|
+
|
|
48
54
|
## Sanity Check
|
|
49
55
|
|
|
50
56
|
For each candidate, ask:
|
|
@@ -40,7 +40,9 @@ const RULE_CONFIG = {
|
|
|
40
40
|
'jsx-a11y/no-noninteractive-element-to-interactive-role': 'error',
|
|
41
41
|
// A tabpanel with no focusable content takes tabIndex=0 (ARIA Authoring Practices).
|
|
42
42
|
'jsx-a11y/no-noninteractive-tabindex': ['error', { roles: ['tabpanel'] }],
|
|
43
|
-
|
|
43
|
+
// Safari drops <ul> list semantics with list-style: none; role="list" restores
|
|
44
|
+
// them (WebKit bug 170179). Keep all other redundant roles flagged.
|
|
45
|
+
'jsx-a11y/no-redundant-roles': ['error', { ul: ['list'] }],
|
|
44
46
|
'jsx-a11y/no-static-element-interactions': 'error',
|
|
45
47
|
'jsx-a11y/prefer-tag-over-role': 'error',
|
|
46
48
|
'jsx-a11y/role-has-required-aria-props': 'error',
|
|
@@ -74,6 +76,22 @@ function forwardsOnlySdkHandlers(tag) {
|
|
|
74
76
|
);
|
|
75
77
|
}
|
|
76
78
|
|
|
79
|
+
const PASSIVE_AUTOPLAY_HANDLERS = new Set([
|
|
80
|
+
'onMouseEnter',
|
|
81
|
+
'onMouseLeave',
|
|
82
|
+
'onFocus',
|
|
83
|
+
'onBlur',
|
|
84
|
+
'onFocusCapture',
|
|
85
|
+
'onBlurCapture',
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
/** Carousel roots observe hover/focus to pause autoplay; these handlers do not activate the region. */
|
|
89
|
+
function pausesAutoplayOnly(tag) {
|
|
90
|
+
if (!isSdkRoot(tag) || !tag.includes('data-pause-button-visibility=')) return false;
|
|
91
|
+
const handlers = [...tag.matchAll(/\b(on[A-Z]\w*)=\{[^}]*\}/g)];
|
|
92
|
+
return handlers.length > 0 && handlers.every(([, name]) => PASSIVE_AUTOPLAY_HANDLERS.has(name));
|
|
93
|
+
}
|
|
94
|
+
|
|
77
95
|
/** Roles whose native element cannot express a styled component. */
|
|
78
96
|
const ROLES_WITHOUT_NATIVE_TAG = new Set(['img', 'presentation', 'none', 'group', 'status']);
|
|
79
97
|
|
|
@@ -93,6 +111,12 @@ function roleHasNoNativeTag(tag) {
|
|
|
93
111
|
* `rules` is skipped when the opening tag of the reported element matches `tag`.
|
|
94
112
|
*/
|
|
95
113
|
const EXEMPTIONS = [
|
|
114
|
+
{
|
|
115
|
+
// ANIMATED-COMPONENTS.md requires the noninteractive carousel root to
|
|
116
|
+
// observe hover and focus so autoplay stops while a visitor is using it.
|
|
117
|
+
rules: new Set(['jsx-a11y/no-noninteractive-element-interactions']),
|
|
118
|
+
tag: pausesAutoplayOnly,
|
|
119
|
+
},
|
|
96
120
|
{
|
|
97
121
|
// SDK handlers (`onClick`, `onMouseIn`, ...) are forwarded on the root
|
|
98
122
|
// element, which carries `id={id}`; the root itself is not the control.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: wix-headless-
|
|
3
|
-
description: "Build a Wix Headless site fast by wiring SHIPPED, verified @wix/sdk code instead of authoring the integration from recipes. Each Wix business vertical ships a typed, framework-agnostic React core (data layer returning plain DTOs, hooks, headless components) plus an Astro overlay (SSR pages with owner-editable SEO pre-wired) and a build-time REST seed script — the agent scaffolds via the Wix CLI, deploys the shipped code, seeds the backend, designs the presentation layer itself on the shipped hooks (product card/grid, PDP, home, theme), and releases to Wix hosting. Works on Wix-managed Astro (ambient auth, the default) and on any React-based project (Vite, non-Astro) over the public OAuth client id. Verticals: stores/storefront (products, categories, variants, cart, hosted checkout), bookings (services, appointment/class time slots, staff, booking form, checkout-or-place), blog (posts, categories/tags, rich content), cms (structured content collections), forms (schema-driven visitor forms: render, validate, submit), events (listing, RSVP, ticket sales), members (login, gated pages, account), portfolio (project collections, media galleries), pricing-plans (plan grid, hosted purchase), restaurants (menus, online ordering, table reservations). Triggers: build me a store/blog/booking/event/restaurant/portfolio site fast, take appointments fast, sell tickets or membership plans headless, wix headless
|
|
2
|
+
name: wix-headless-kit
|
|
3
|
+
description: "Build a Wix Headless site fast by wiring SHIPPED, verified @wix/sdk code instead of authoring the integration from recipes. Each Wix business vertical ships a typed, framework-agnostic React core (data layer returning plain DTOs, hooks, headless components) plus an Astro overlay (SSR pages with owner-editable SEO pre-wired) and a build-time REST seed script — the agent scaffolds via the Wix CLI, deploys the shipped code, seeds the backend, designs the presentation layer itself on the shipped hooks (product card/grid, PDP, home, theme), and releases to Wix hosting. Works on Wix-managed Astro (ambient auth, the default) and on any React-based project (Vite, non-Astro) over the public OAuth client id. Verticals: stores/storefront (products, categories, variants, cart, hosted checkout), bookings (services, appointment/class time slots, staff, booking form, checkout-or-place), rentals (rooms, vehicles, gear by the hour or the day: resources, customer-picked length, priced quote, checkout), blog (posts, categories/tags, rich content), cms (structured content collections), forms (schema-driven visitor forms: render, validate, submit), events (listing, RSVP, ticket sales), members (login, gated pages, account), portfolio (project collections, media galleries), pricing-plans (plan grid, hosted purchase), restaurants (menus, online ordering, table reservations), faq (categorized questions and answers, search, a link per question), donations (campaign pages, goal progress, one-time and recurring donations via hosted checkout). Triggers: build me a store/blog/booking/rental/event/restaurant/portfolio/FAQ/donation site fast, take appointments fast, rent out rooms/cars/equipment headless, sell tickets or membership plans headless, collect donations headless, wix headless kit, connect a Wix business app with ready-made SDK code."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Wix Headless
|
|
6
|
+
# Wix Headless Kit
|
|
7
7
|
|
|
8
8
|
Build a Wix Headless site on **shipped, verified code instead of authoring the integration**.
|
|
9
9
|
Each vertical ships the integration itself — a typed data layer, hooks, components, pages, and a
|
|
@@ -74,7 +74,13 @@ doesn't express — or once the site exists and the work turns to managing or ex
|
|
|
74
74
|
`capabilities.mediaUpload.policies` entry to the plan; Fast ships its client helper, Astro
|
|
75
75
|
endpoint, dependencies, and generated policy module once. Read
|
|
76
76
|
`templates/shared/CUSTOM_OPERATIONS.md` before choosing it. The agent wires the helper to
|
|
77
|
-
the product UI; it never authors or widens the endpoint.
|
|
77
|
+
the product UI; it never authors or widens the endpoint. For a site-wide search (a header box
|
|
78
|
+
with suggestions, a `/search?q=` page over the deployed verticals' products, services, posts
|
|
79
|
+
and events), add a `capabilities.siteSearch` entry; Fast ships its data layer, stores, hooks,
|
|
80
|
+
components and search page once. Enabling it means the Wix Site Search app is installed on the
|
|
81
|
+
site by the seed step (`install: true`; the capability's `seed/install.mjs`, run after the
|
|
82
|
+
content seed) — the index fills within about half a minute of the install. Playbook:
|
|
83
|
+
`templates/shared/capabilities/site-search/INSTRUCTIONS.md`.
|
|
78
84
|
|
|
79
85
|
## The run
|
|
80
86
|
|
|
@@ -83,9 +89,26 @@ Needed throughout: Node ≥ 20.11, git, a logged-in Wix CLI (`npx @wix/cli@lates
|
|
|
83
89
|
read tokens into context), and the two companion skills beside this one, `wix-docs` and
|
|
84
90
|
`wix-manage` (if `.agents/skills/` lacks them:
|
|
85
91
|
`CI=1 npx skills@latest add wix/skills --skill wix-docs --skill wix-manage --yes`). The cold-start
|
|
86
|
-
page, `cold-start/cold-start.md`, gets a machine with none of this to that point.
|
|
92
|
+
page, `cold-start/cold-start.md`, gets a machine with none of this to that point. In a folder that
|
|
93
|
+
already holds a `wix.config.json`, `node <SKILL_ROOT>/install/context.mjs` first: it runs
|
|
94
|
+
`wix env pull` when `.env.local` is missing and prints the folder's **shape** (`folder.shape`, the
|
|
95
|
+
cases of step 3, with the `next` for each) and the two identities a project has — the deploy site
|
|
96
|
+
(the config, where `wix release` goes) and the content site (the env, whose app the SDK client runs
|
|
97
|
+
as and whose dashboard manages the business). They are one site, except on a **migration preview**
|
|
98
|
+
(`guides/migration.md`), where the env names the site being migrated. Every script here reads that
|
|
99
|
+
context; the site a call targets is never guessed from the config alone. Then fetch the shipped
|
|
87
100
|
code once: `node <SKILL_ROOT>/install/templates.mjs`. It prints the folder;
|
|
88
101
|
the `templates/…` paths below are relative to `<SKILL_ROOT>`, where it lands.
|
|
102
|
+
`node <SKILL_ROOT>/install/check.mjs` says whether the skill or its templates have a newer version
|
|
103
|
+
and prints the update commands; it changes nothing.
|
|
104
|
+
|
|
105
|
+
Throughout any run: if the user asks to send feedback to Wix, complains or gets frustrated, or the
|
|
106
|
+
run hits friction of any kind: anything that cost more turns than it should have, whether or not
|
|
107
|
+
it ended in an error (a confusing error, a doc gap, a seed that had to be re-run, a shipped file
|
|
108
|
+
that did not cover the brief, a playbook line you had to read the source to understand, a call you
|
|
109
|
+
had to work out by trial, a workaround you had to invent, a slow or flaky step, a platform gate),
|
|
110
|
+
offer to relay it to Wix per `<SKILL_ROOT>/guides/feedback.md`. Default to offering rather than waiting to be asked; send
|
|
111
|
+
only after an explicit yes, never automatically. Step 5 ends with the same self-check.
|
|
89
112
|
|
|
90
113
|
1. **Resolve the stack.** Default is **Wix-managed Astro** — take it unless the user names
|
|
91
114
|
another framework or the directory already holds one. Then, by what the shipped code can run
|
|
@@ -128,52 +151,58 @@ the `templates/…` paths below are relative to `<SKILL_ROOT>`, where it lands.
|
|
|
128
151
|
the OAuth app's allowed domains before checkout can return to it.
|
|
129
152
|
- **Static** (no build): `outputDirectory` points at the folder the pages live in; a route is a
|
|
130
153
|
page plus a query-string slug (reference mode).
|
|
131
|
-
2. **The seed plan.**
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
("Supplied content"), every entry, names and prices verbatim, their images and no others
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
154
|
+
2. **The seed plan.** The brief decides what is seeded; a site this run makes always opens with content:
|
|
155
|
+
|
|
156
|
+
| the brief | the plan |
|
|
157
|
+
|---|---|
|
|
158
|
+
| supplies the content in any form: a CSV, JSON or spreadsheet, a list in the prompt, a PDF price list, a folder of photos and a text file, a link to their current catalog, anything that names the content | that IS the plan: map it into `plan.json` per `templates/shared/SUPPLIED-CONTENT.md` and the vertical's `SEED.md` ("Supplied content"), every entry, names and prices verbatim, their images and no others |
|
|
159
|
+
| describes the content without listing it ("a store for hand-poured candles, four of them", "a dozen FAQ questions in three groups") | draft a plan from the description per the vertical's `SEED.md` (read only that for this; save `INSTRUCTIONS.md` for step 4) |
|
|
160
|
+
| says nothing about content ("build me a store") | on a site this run makes (create, adopt) draft a plan per the vertical's `SEED.md` so the site opens with content, and say in the closing message that it is placeholder content and where to replace it; on a site that existed before the run (attach, iterate, published-static, migrate) no plan and no seed: the site holds what the owner put there |
|
|
161
|
+
|
|
162
|
+
**An existing site has no plan of its own**: when the brief names a site by its id, or the
|
|
163
|
+
folder's config does, the site holds the content already; the frontend reads what is there
|
|
164
|
+
(step 3's attach path), and only content the brief supplies or describes is added to it.
|
|
141
165
|
3. **Set up the project, in its folder** — one deterministic call, the same for an empty folder
|
|
142
|
-
and for a project already on disk; **the folder decides** what it does:
|
|
166
|
+
and for a project already on disk; **the folder decides** what it does, from five file facts:
|
|
167
|
+
`wix.config.json`, its `site.outputDirectory`, the migration variables in `.env.local`,
|
|
168
|
+
`package.json`, `index.html`. `node <SKILL_ROOT>/install/context.mjs` prints the shape it reads
|
|
169
|
+
and the `next` for it. **The brief is the instruction**: what it asks to switch on is installed
|
|
170
|
+
on the site the folder names, without asking again. Ask only when acting would create a second
|
|
171
|
+
site for a folder that already has one, or when a cleanup seems needed.
|
|
143
172
|
|
|
144
173
|
```bash
|
|
145
|
-
node <SKILL_ROOT>/install/setup.mjs --vertical <vertical> [--plan plan.json] [--business-name "<Brand>"]
|
|
174
|
+
node <SKILL_ROOT>/install/setup.mjs --vertical <vertical>[,<vertical>…] [--plan plan.json] [--business-name "<Brand>"] [--stack <stack>]
|
|
146
175
|
```
|
|
147
176
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
177
|
+
Name every vertical the brief needs in this one call (a store with member accounts is
|
|
178
|
+
`storefront,members`): the first one's template scaffolds the project; the others deploy in the
|
|
179
|
+
same call, so the one install covers them all. A vertical added after the install has started
|
|
180
|
+
costs a second install.
|
|
181
|
+
|
|
182
|
+
| the folder holds | shape | what setup does | seeded by setup |
|
|
183
|
+
|---|---|---|---|
|
|
184
|
+
| nothing, or loose files (a CSV, a brief) | **empty** → create | `wix create` with the vertical's composed template, here; `--business-name` names the site | **yes**, from `--plan` |
|
|
185
|
+
| a frontend, no config (a `package.json`, or `index.html` at the root: someone's Astro, Vite, Next, plain HTML) | **project** → adopt | `init` in place gives it a new, empty site, then deploys; `--stack` from step 1 is required; make the project what that stack needs on Wix hosting (step 1) before or right after | **yes**, from `--plan` |
|
|
186
|
+
| a config whose `.env.local` declares an active editor migration (`EDITOR_MIGRATION_STATUS=ACTIVE`), with or without the blank Astro starter the download carries | **migration** → migrate | the shipped code into the starter (or the composed template around a bare config), deployed with the migrated site's app as the client, the install starts; `ready_for_brand_layer` says `mode: "migrate"`, the parent as `siteId`, the child as `deploySiteId` (`guides/migration.md`) | no, ever |
|
|
187
|
+
| a config, no frontend | **config-only** → refuses | the site exists and has no frontend yet: `attach.mjs` (below) takes the site from the config, reuses its hosting, scaffolds and deploys | no |
|
|
188
|
+
| a config and a frontend (a `package.json`, or `index.html` inside the folder `site.outputDirectory` names) | **wix-project** → refuses | iterate: never scaffold, `init` or reseed. `deploy.mjs <vertical…> --stack <stack>` adds a solution (the client id comes from `.env.local`, the config as the fallback), then ONE `npm install`; a change is file edits; then release | no |
|
|
189
|
+
| a config, `index.html` at the root, no `package.json` (a site published through the drop flow and downloaded) | **published-static** | the config's site, no `init`: `site/` becomes the upload, the REST layer deploys into `site/js/wix/`; the `next` says to move the pages, styles and assets in; release keeps the URL | no |
|
|
190
|
+
|
|
191
|
+
**Setup seeds only a site it created in this run** (create and adopt: the site is empty by
|
|
192
|
+
construction, so the plan from step 2 goes in with the one call). A site that existed before
|
|
193
|
+
the run holds content the run did not make: read it first with the vertical's
|
|
194
|
+
`seed/read-site.mjs`, then, when the brief supplies or describes content, run the vertical's
|
|
195
|
+
seed module yourself with a plan (from the project root:
|
|
196
|
+
`node <SKILL_ROOT>/templates/<vertical>/seed/seed-<vertical>.mjs plan.json`). Seeds are
|
|
197
|
+
additive and idempotent by name; nothing on a site is ever deleted or overwritten.
|
|
198
|
+
|
|
167
199
|
- The brief names a site by id → not this call: read `<SKILL_ROOT>/guides/existing-site.md`
|
|
168
200
|
and follow it (read the site, then `attach.mjs`, which does what setup does against the
|
|
169
201
|
site given; self-hosting and a project already on disk are in there too).
|
|
170
202
|
|
|
171
|
-
`--vertical` is required and picks which shipped code deploys AND which seed runs
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
gets none. Seeding is **additive**: it never deletes or overwrites what the site holds; if a
|
|
175
|
-
cleanup seems needed, ask. The `ready_for_brand_layer` event says `mode` (create or
|
|
176
|
-
connect), the stack, and the `next` for that stack, including how it releases.
|
|
203
|
+
`--vertical` is required and picks which shipped code deploys AND which seed runs. The
|
|
204
|
+
`ready_for_brand_layer` event says `mode` (`create`, `adopt`, `migrate`, `published-static`),
|
|
205
|
+
`shape`, the stack, and the `next` for that stack, including how it releases.
|
|
177
206
|
|
|
178
207
|
setup scaffolds with `--skip-git`: it composes its own steps and leaves version control to
|
|
179
208
|
you / the enclosing repo, so it does **not** create the scaffold's usual git repo + initial
|
|
@@ -224,7 +253,7 @@ the `templates/…` paths below are relative to `<SKILL_ROOT>`, where it lands.
|
|
|
224
253
|
your summary — if non-zero, read `seed.log` and re-run the seed module manually). Those two
|
|
225
254
|
seed files exist **only when setup started the seed** (attach runs none: only the install
|
|
226
255
|
marker is waited on). When you ran `seed-store.mjs`
|
|
227
|
-
yourself (
|
|
256
|
+
yourself (adopt, iterate and published-static runs, reference mode), there is no marker to wait for: the process's
|
|
228
257
|
exit code is the result and its stdout is the JSON — wait on the process (a foreground run,
|
|
229
258
|
or `wait` on its pid), not on a file. Then
|
|
230
259
|
**build & release once** (managed), as the `next` of the `ready_for_brand_layer` event says
|
|
@@ -235,9 +264,15 @@ the `templates/…` paths below are relative to `<SKILL_ROOT>`, where it lands.
|
|
|
235
264
|
build+release mid-flow; backend content is fetched at
|
|
236
265
|
runtime, so a re-release never "refreshes" seeded data. The run is complete only when the
|
|
237
266
|
site is released — close with the live URL and the dashboard link
|
|
238
|
-
`https://manage.wix.com/dashboard/<siteId
|
|
267
|
+
`https://manage.wix.com/dashboard/<siteId>` (the `siteId` of the `ready_for_brand_layer`
|
|
268
|
+
event: on a migration preview that is the migrated site's dashboard, the release URL is the
|
|
269
|
+
preview's, the original site is unchanged, and completing the migration is the user's next
|
|
270
|
+
step in the Wix CLI once they approve — say all three). **Copy the live URL verbatim from the
|
|
239
271
|
`wix release` output — never retype it from memory** (a mistyped subdomain hands the user
|
|
240
|
-
a 404).
|
|
272
|
+
a 404). Before you sign off, run the feedback self-check over the whole session
|
|
273
|
+
(`guides/feedback.md`): anything that cost more turns than it should have, including what you
|
|
274
|
+
recovered from silently, is signal; if anything qualifies, offer to relay it as you deliver the
|
|
275
|
+
links, and send only after an explicit yes.
|
|
241
276
|
|
|
242
277
|
## Reference mode — a static site, or a server-rendered app in another language
|
|
243
278
|
|
|
@@ -252,10 +287,17 @@ close.
|
|
|
252
287
|
|
|
253
288
|
## Verticals
|
|
254
289
|
|
|
290
|
+
The shortlist. Match the brief against the first column; when it names a Wix product or a
|
|
291
|
+
feature not here, when two rows could fit, or when the request sounds like something this skill
|
|
292
|
+
does not ship (meetings, gift cards, loyalty, groups), read
|
|
293
|
+
`<SKILL_ROOT>/guides/capabilities.md`: every Wix product, what it covers, which vertical here
|
|
294
|
+
ships it and what is not shipped.
|
|
295
|
+
|
|
255
296
|
| The user wants… | Vertical | Playbook |
|
|
256
297
|
| -------------------------------------------------------------------------------------------- | ----------------- | ------------------------------------------ |
|
|
257
298
|
| Online store: products, categories, variants, cart, checkout | **storefront** | `templates/storefront/INSTRUCTIONS.md` |
|
|
258
299
|
| Appointments/classes: services, time slots, staff, booking, checkout | **bookings** | `templates/bookings/INSTRUCTIONS.md` |
|
|
300
|
+
| Rentals: rooms, vehicles, gear rented by the hour or the day, customer-picked length, checkout | **rentals** | `templates/rentals/INSTRUCTIONS.md` |
|
|
259
301
|
| Blog: post feed, categories/tags, rich-content post pages | **blog** | `templates/blog/INSTRUCTIONS.md` |
|
|
260
302
|
| Structured content collections (directory, recipes, listings) with pages designed per schema | **cms** | `templates/cms/INSTRUCTIONS.md` |
|
|
261
303
|
| Any visitor-fillable form: contact/enquiry, signup, application, survey — rendered from the live schema | **forms** | `templates/forms/INSTRUCTIONS.md` |
|
|
@@ -264,10 +306,14 @@ close.
|
|
|
264
306
|
| Portfolio/showcase: collections of projects, project pages with media galleries | **portfolio** | `templates/portfolio/INSTRUCTIONS.md` |
|
|
265
307
|
| Membership/subscription plans: pricing page, plan detail, hosted purchase | **pricing-plans** | `templates/pricing-plans/INSTRUCTIONS.md` |
|
|
266
308
|
| Restaurant: menu with photos, online ordering, table reservations | **restaurants** | `templates/restaurants/INSTRUCTIONS.md` |
|
|
309
|
+
| FAQ: questions grouped by category, search, expandable answers, a link per question | **faq** | `templates/faq/INSTRUCTIONS.md` |
|
|
310
|
+
| Donations: campaign pages, goal progress, one-time and recurring giving via hosted checkout | **donations** | `templates/donations/INSTRUCTIONS.md` |
|
|
267
311
|
|
|
268
312
|
Verticals compose: a brief that spans several (a restaurant with a blog, a store with member
|
|
269
|
-
accounts)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
313
|
+
accounts) names them all in the setup call (`--vertical restaurants,blog`), so one install covers
|
|
314
|
+
them; each vertical's seed runs with its own plan. On a project already built,
|
|
315
|
+
`node <SKILL_ROOT>/install/deploy.mjs <vertical…>` from the project root adds one, then one
|
|
316
|
+
`npm install`, then its seed. A request that matches no shipped vertical has no shipped
|
|
317
|
+
code: say so in one line, then build it from the Wix API reference through `wix-docs` (search,
|
|
318
|
+
then the method page), with the same rule as every other call, on the same project and stack,
|
|
319
|
+
starting from the closest shipped vertical when one exists (`guides/capabilities.md` says which).
|