Control flow

Guide: Control flow.

ExportSignature
show(ctx, cond: bool, then: *Node, else_: ?*Node) *Node
forEach(ctx, comptime ItemT, items: []const ItemT, items_ctx, comptime keyFn: fn (Ctx, ItemT) []const u8, comptime renderFn: fn (Ctx, *const Context, ItemT) anyerror!*Node) !*Node
portal(ctx, target_selector: []const u8, child: *Node) *Node
createErrorBoundarybuilds an ErrorBoundary; render-time variant is ctx.errorBoundary(inner, fallback)

Notes:

  • show evaluates both branches at the call site — it's a function, not a macro.
  • forEach emits <ul class="verve-for"> with <li data-vkey="…"> children; keys drive the client reconciler's move/insert/remove planning (and the FLIP fast path).
  • portal renders inline server-side inside <template data-vportal="sel">; the client relocates on hydrate.

Slots & templates

ctx.template(name, inner) declares <template data-vt="name">; inner nodes marked .slot("field") become fill targets. Chunk side:

ExportPurpose
cloneTemplate(name)instantiate a clone
slotText(clone, slot, text) / slotAttr(...)fill slots
Slot / SlotMapserver-side slot bookkeeping

Keyed list reconciliation (chunk side)

listDiff(parent_bind, old_keys, new_keys, new_html) — plans minimal insert/move/remove against the live DOM. parent_bind is not vid-scoped automatically; suffix "<bind>__v{d}" with the hydrate root_id for binds inside the island's own markup.