Building Views with el

Use the el package for HTML, SVG, events, conditional rendering, keyed lists, and runtime bootstrap in normal Vango apps.

#el#rendering#html#svg

Building Views with el

The el package is the normal UI DSL for Vango apps.

It provides:

  • HTML constructors

  • SVG constructors

  • attribute helpers

  • event helpers

  • conditional rendering helpers

  • list helpers

  • client boundary helpers

Basic shape

go
1Div(
2	Class("p-4"),
3	H1(Text("Hello")),
4	Button(OnClick(doThing), Text("Click")),
5)

Elements and attributes

Use the obvious constructors and helpers:

  • Div , Span , Button , Input , Form , Section , Main , Nav

  • Class , ID , Href , Type , Value , Checked , Placeholder , Disabled

For attributes that do not have dedicated helpers yet, use Attr(key, value).

Events

Prefer the most specific typed event helper available.

go
1Button(OnClick(save), Text("Save"))
2Input(OnInput(name.Set))
3Form(OnSubmit(vango.PreventDefault(func() {
4	submit.Run(form.Values())
5})))

For client-boundary communication, use the explicit helpers:

  • OnEvent(...)

  • OnEventValidated(...)

  • OnIslandMessage(...)

  • OnIslandMessageValidated(...)

  • OnWASMMessage(...)

  • OnWASMMessageValidated(...)

Conditional rendering

Vango includes helpers like:

  • If

  • IfElse

  • When

  • Unless

  • Either

  • Switch

  • Case_

  • Maybe

  • Show

Use the helper that makes branch structure obvious. If a normal Go if in the render closure is clearer, use that instead.

Lists and identity

Use RangeKeyed for dynamic lists.

go
1RangeKeyed(items,
2	func(it Item) string { return it.ID },
3	func(it Item) *vango.VNode {
4		return Li(Text(it.Name))
5	},
6)

Never use:

  • list indices

  • random keys

  • mutable labels as identity

Stable identity is even more important when list items contain hooks, islands, or WASM boundaries.

Raw HTML

Default text rendering is escaped. That is the safe path.

Use raw HTML only when it is explicit and trusted:

go
1DangerouslySetInnerHTML(SanitizeTrustedHTML(trustedHTML))

Do not feed user HTML into raw sinks without a real sanitizer.

Runtime scripts

Most layouts should include RuntimeScripts(ctx).

That is the canonical bootstrap helper for:

  • live runtime endpoint defaults

  • reconnect policy

  • request-scoped CSRF token delivery

  • surface and shell metadata

Use RuntimeScripts(ctx) for normal layouts instead of lower-level script helpers.

Desktop and mobile surfaces

App code can read ctx.Surface() for environment facts and ctx.Shell() for native host capabilities.

Use:

  • ctx.Surface() for web, desktop, mobile, platform, and topology facts

  • ctx.Shell() for native actions like title changes, notifications, dialogs, or deep-link events

Keep shared app code topology-neutral unless you truly need a surface-specific branch.

Test IDs

Use TestID(...) for automated tests on important interaction points.

Apply test IDs to:

  • buttons users click in tests

  • inputs users type into

  • important output nodes

  • structural containers you query frequently

If you are ready to move from rendering to route-level app structure, continue to Routing and APIs.