---
name: vizen-widgets
description: Configure Vizen's built-in blocks — header, menu, footer, product listing, product card, covers, cards, slideshow — through their props, and know where their limits are. Use to configure built-in blocks through props; for authored markup and CSS integration, follow vizen-own-markup.
---

# Platform widgets

The fast path: live data, working sticky header, working dropdowns, filters and
paging. Props configure the standard look; layout CSS can restyle it through
the declared markup hooks (§3).

## 1. Where the truth about props lives

```
GET /docs/widgets
```

Generated from the real widget parsers, so it cannot drift from the platform. For
each kind: label, whether it is chrome or a page block, **the write path**, a
JSON Schema of its props with defaults, and the allowed values of every enum.

Read the schema of the kind you are about to change. Do not write a prop from
memory: an unknown value is accepted and the default is drawn.

## 2. The write path is where agents go wrong

Props are nested per widget: `props.listing.…`, `props.card.…`, `props.form.…`.
The reference states `writePath` for each kind — use it. Writing to the root of
`props` is accepted and does nothing.

`sections` is a **replace-set**: read the block, change the one element, send the
whole list back. Sending a single section deletes the rest.

## 3. The wrapper is configurable too — and it is how you reskin a widget

Every block sits in a standard wrapper, and its axes are written at the root of
`payload.props` (beside the widget's own nest such as `props.component`) — not next
to `kind` and not inside the widget's own path. Ask for the current
list rather than trusting any copy of it — one that named a `props.innerMax`
nothing had ever read survived for weeks:

```bash
curl -s https://api.vizen.shop/docs/widgets | jq -r '
  .wrapper.axes[] | [.path, .type, (.default // "-"), .anchor.at] | @tsv'
```

Each row carries the `file:line` in the storefront that sets the default, and
`.wrapper.elements` does the same for the two wrapper divs themselves.

**When the props run out, consider styling the wrapper to retain built-in behaviour.**
`props.wrapperClass: "my-hero"` puts your own class on the band — including the
band of `siteHeader`, `siteMenu` and `siteFooter` — and you restyle it from your
own CSS (`.my-hero > .vz-inner { … }`). You keep the working widget, its live
data and its props, and change only the look. Put the CSS in the **layout folder**
or a level-3 document; level-1 local styles cannot cross its shadow boundary.
Prefer your own class to limit side effects; supported selectors are listed in
`/docs/vz-keys.json` → `markup_contract`. Inspect the DOM for intentional overrides. Recipe:
`GET /docs/own-markup` §5, skill `vizen-own-markup`.

Per-device overrides live under `props.tablet` and `props.mobile`, same keys.

## 4. Known limits — say them out loud before promising a look

- `container.fill` on `productListing` is accepted and does nothing. This is
  a prop limitation; use layout CSS and supported hooks for intentional styling;
- the listing template is `default` and there are no others;
- `siteMenu.level2` builds a real dropdown from your category tree — it opens
  **on click**, not on hover, whatever the field description says;
- some style props are clamped: a font weight of 800 renders as 600, a label size
  of 13 renders as 15.

**Quick view from the listing.** `props.listing.cardClick: "modal"` opens the
product in a window instead of navigating, `showQuickViewButton: true` adds a
button to every tile; the window is set by `modalSize` (`small`|`medium`|`full`),
`modalTpl`, `modalNav` and the booleans `modalHead`/`modalFoot` — the last two
have no default, so `/docs/widgets` does not list them. Recipe and the same
window from your own markup: `/docs/widgets-area` §5 and `/docs/webcoding` §14.3.

For changes beyond props, choose layout CSS or `vizen-own-markup` depending on
the desired markup and behaviour. Own product rows can use live `products[]` on
a catalogue section page (up to 48 items); other contexts and hand-written
values have different data limits. Read `/docs/own-markup` §2 before choosing.
Tell the owner which limits affect the requested design before implementation.

## 5. Validate before writing

`POST /docs/validate` with the sections you are about to send. It replies per
path whether the value will be applied, silently ignored, or not understood —
which is exactly the class of mistake this area produces most. Nothing is
written.

## 6. Verify

Re-read the block and open the page. A 200 is not evidence. Full checklist:
`vizen-troubleshoot`.
