Conditional content
A FAQ is a handful of x.When subtrees: a button toggles a bool with x.Not, and the answer mounts and unmounts as it changes. The first answer is open at build time, so the page reads correctly with JavaScript disabled — and with it on, the answers appear and disappear in place.
The markers render at build time and subscribe in the browser — the page reads correctly with JavaScript disabled.
How it works
State
var XFaq1 = x.Named("faq1", true)
var XFaq2 = x.Named("faq2", false)
var XFaq3 = x.Named("faq3", false)One bool per question. The first starts open, so the page has static content; the rest start closed.
The toggle
@x.El("button", x.On("click", XFaq1.Set(x.Not(XFaq1))), x.Class("on", XFaq1)) {
What is compiled markup?
}x.Not negates the signal, so clicking always flips it — no if/else. x.Class("on", …) highlights the open questions, so the state is visible before you read any answers.
The answer
@x.When(XFaq1, xFaqAnswer("The markers render at build time and subscribe in the browser."))
// xFaqAnswer is the subtree When mounts and unmounts.
templ xFaqAnswer(text string) {
<p class="demo-note">{ text }</p>
}x.When takes the condition and the subtree to mount — a plain templ component. It mounts while the condition is true and unmounts when it turns false, and the HTML is captured at build time, so the answer is in the page source before any script runs.
Full source
var XFaq1 = x.Named("faq1", true)
var XFaq2 = x.Named("faq2", false)
var XFaq3 = x.Named("faq3", false)
templ XFaqDemo() {
<div class="demo">
@x.El("button", x.On("click", XFaq1.Set(x.Not(XFaq1))), x.Class("on", XFaq1)) {
What is compiled markup?
}
@x.When(XFaq1, xFaqAnswer("The markers render at build time and subscribe in the browser — the page reads correctly with JavaScript disabled."))
@x.El("button", x.On("click", XFaq2.Set(x.Not(XFaq2))), x.Class("on", XFaq2)) {
When should I reach for WebAssembly instead?
}
@x.When(XFaq2, xFaqAnswer("When the behaviour is a program — canvas, fetching, timers. Markers cover state, bindings and structure; everything else is Go in the browser."))
@x.El("button", x.On("click", XFaq3.Set(x.Not(XFaq3))), x.Class("on", XFaq3)) {
What happens without JavaScript?
}
@x.When(XFaq3, xFaqAnswer("The page keeps its static form — the first answer is already open. Nothing needs a script to be readable."))
</div>
}
templ xFaqAnswer(text string) {
<p class="demo-note">{ text }</p>
}
// On the page: @x.Document(XFaqDemo())When vs Show
x.Show keeps the same nodes and toggles visibility, so input focus and scroll position inside them survive. x.When removes the subtree entirely and rebuilds it from the captured HTML on remount — right for content rebuilt from state, wrong for a form you'd like to keep typing in.