Data

A repeater container. Same DOM output and layout behavior as [Container](container.md) — one element, no extra wrapper — but its children act as a template that repeats per item from a data source.

A repeater container. Same DOM output and layout behavior as Container — one element, no extra wrapper — but its children act as a template that repeats per item from a data source.

The moment a section binds to a connector (Stripe, customer orders) or repeats off a parent item array, switch from Container to Data. Convert existing nodes via MCP typePatch: "Data".

Key files

Key props

PropNotes
typeSame enum as Container (drives HTML tag).
dataSourceThe binding. See data-bindings. Shape: { provider, collection, filter?, sort?, limit?, scope?, splitBy?, stateInputs?, publishStateKeys?, bindingKey? }.
All other Container propsIdentical (className, root, attrs, handlers, click, …).

dataSource modes

  • Connector-backed: { provider: "stripe", collection: "products", filter: { demo: "true" } } — fetched at SSR and keyed under connector.<provider>.bindings.<bindingId>.
  • Scope (nested): { scope: "item.images" } — iterates a path INTO the parent repeater item. Skipped by SSR scanner; resolves locally at render. Strings get wrapped as { id, value, title, slug, src, image }.
  • Comma-split scope: { scope: "item.metadata.sizes", splitBy: "," } — split a string into pseudo-items.

Variable interpolation

Children interpolate via {{item.*}}. Resolves in:

  • Text — inline <span data-variable="item.title" class="variable-node">{{item.title}}</span>.
  • Button text, action.href, attrs values — bare {{item.*}}.
  • Image src/alt — via replaceVariables.

Gotchas

  • walkPath splits on . only. {{item.images[1]}} does NOT resolve — use {{item.images.1}}.
  • || fallback supports ONE level and the fallback is a literal string. For "fallback to another variable" use a conditional visibility item condition (key: "images.1", operator: "exists").
  • bindingKey keeps connector ids stable when multiple sections share the same collection.
  • stateInputs: { <fetchOption>: <stateKey> } subscribes the connector to state keys (e.g. { q: "url:q", category: "url:category", page: "url:page" }). When any subscribed key changes the connector refetches with the merged snapshot. The URL ↔ state bridge in useViewerSetup mirrors ?q=…state["url:q"] automatically.
  • publishStateKeys: { totalPages, totalCount, page, count } writes fetch metadata back into the registry so pagination chrome can interpolate {{state.<key>}} or gate visibility via state conditions.

Related