8. Interactivity
Static until now. The x package adds live behaviour without WASM: markers are templ components that render the current value and generate the JavaScript that keeps it live, in the same call. The counter below is running right now.
pages/home.templ:
package pages
import x "github.com/LukasDerBaum42/astwerk/x"
// count is the site's one piece of state. It is named so scripts can read it;
// every page that renders counter() shares it.
var count = x.Named("count", 0)
templ Home(title string, path string, prefix string) {
@Layout(title, path, prefix) {
<h1>My Site</h1>
<p>A portfolio built with astwerk.</p>
@x.Document(counter())
}
}
// counter is a live widget: the markers below render the value and generate
// the JavaScript that keeps it in sync.
templ counter() {
<div class="counter">
@x.Text(count)
@x.El("button", x.On("click", count.Set(count.Add(1)))) {
+
}
</div>
}x.Named creates the state under a fixed name, so scripts can read it; x.Text renders the value and generates the binding that keeps it in sync, and x.On does the same for the handler. x.Document emits the runtime and state declarations before its body and the bindings after it. View source on this page: the bindings are embedded right here, and no .wasm was downloaded. Disable JavaScript and the value still renders — it was written statically at build time.
The full marker set — bindings, forms, lists, effects — is in x — compiled reactive markup.
What does @x.Text(count) do?
Markers render at build time and emit their own binding in the same call — the static value is in the HTML and the generated JavaScript updates it.
Try it. Change the counter's initial value from 0 to 5 and rebuild.
What you should see
The button shows 5 before any JavaScript runs — the value is written into the HTML at build time, and the generated script keeps it in sync.
With JavaScript disabled, what does a page with x markers show?
Markers render their current value into the HTML at build time; the generated JavaScript only keeps it in sync. No JavaScript, no framework — the value is still there.