Node API
The Node interface is the fundamental building block. All rendered elements implement it.
See also: Home | Architecture | Pipeline | WebAssembly | Code-Generation
Node Interface
type Node interface {
Render(ctx *Context) string
}
Every node receives a Context and returns an HTML string. Nodes compose into trees via El() children.
Node Types
Text — i18n-Aware Text
func Text(key string, args ...any) Node
Renders localised text through the i18n service in the context. Output is HTML-escaped (safe by default). Supports fmt.Sprintf-style arguments.
html.Text("greeting", userName)
// Looks up "greeting" in locale, formats with userName
// Output: "Hello, Alice" (escaped)
El — HTML Element
func El(tag string, children ...Node) Node
Creates an HTML element. Children are rendered in order. Void elements (br, img, hr, input, meta, link, area, base, col, embed, source, track, wbr) self-close.
html.El("div",
html.El("h1", html.Text("page.title")),
html.El("p", html.Text("page.body")),
)
// <div><h1>Page Title</h1><p>Body text</p></div>
Attr — Attribute Setter
func Attr(n Node, key, value string) Node
Sets an attribute on an element node. Returns the same node for chaining. Values are attribute-escaped.
html.Attr(
html.El("a", html.Text("link.text")),
"href", "/about",
)
// <a href="/about">About</a>
Raw — Unescaped Content
func Raw(content string) Node
Renders content without escaping. Use only for trusted content (pre-sanitised HTML, SVG, etc.).
html.Raw("<svg>...</svg>")
If — Conditional Rendering
func If(cond func(*Context) bool, node Node) Node
Renders the node only when the condition returns true. The condition receives the current context.
html.If(
func(ctx *html.Context) bool { return ctx.Identity != "" },
html.El("span", html.Text("user.welcome")),
)
Unless — Negated Conditional
func Unless(cond func(*Context) bool, node Node) Node
Renders the node when the condition is false. Inverse of If.
html.Unless(
func(ctx *html.Context) bool { return ctx.Identity != "" },
html.El("a", html.Text("auth.login")),
)
Entitled — Feature Gate
func Entitled(feature string, node Node) Node
Renders the node only if the feature is present in ctx.Entitlements. Used for plan/tier-gated UI.
html.Entitled("analytics-pro",
html.El("div", html.Text("analytics.advanced_panel")),
)
Switch — Runtime Case Selection
func Switch(selector func(*Context) string, cases map[string]Node) Node
Evaluates the selector at render time and renders the matching case. No output if no case matches.
html.Switch(
func(ctx *html.Context) string { return ctx.Data["theme"] },
map[string]html.Node{
"dark": html.El("div", html.Attr(html.El("div"), "class", "dark")),
"light": html.El("div", html.Attr(html.El("div"), "class", "light")),
},
)
Each — Generic Iteration
func Each[T any](items []T, fn func(T) Node) Node
Iterates over a typed slice, calling the function for each item. Uses Go generics.
type Article struct { Title, Slug string }
html.Each(articles, func(a Article) html.Node {
return html.El("li",
html.Attr(html.El("a", html.Text(a.Title)), "href", "/"+a.Slug),
)
})
Context
type Context struct {
Identity string
Locale string
Entitlements map[string]bool
Data map[string]string
Service *i18n.Service
}
func NewContext() *Context
func NewContextWithService(svc *i18n.Service) *Context
| Field | Purpose |
|---|---|
Identity |
Current user identifier |
Locale |
Language code for i18n lookups |
Entitlements |
Feature flags for Entitled() gating |
Data |
Arbitrary string data for Switch() selectors |
Service |
go-i18n service for Text() rendering |
Convenience
func Render(node Node, ctx *Context) string
Shorthand for node.Render(ctx). Useful in pipelines.