wasmwrap & templ
wasmwrap without reactive
reactive is optional. Every other demo in this section uses it, but wasmwrap alone is enough for scripting that doesn't need signals — a nav toggle is three lines. See wasmwrap.
//go:build js && wasm
package main
import "github.com/LukasDerBaum42/astwerk/wasmwrap"
func main() {
nav := wasmwrap.Query("#nav")
wasmwrap.Query("#toggle").On("click", func(e wasmwrap.Event) {
e.PreventDefault()
nav.Class().Toggle("open")
})
select {}
}Why select {} is there
When main returns, the WASM instance exits and every handler dies with it. select blocks forever, keeping the module alive for the click handler.
Re-rendering templ client-side
BindTempl runs a templ component in the browser and assigns the result as innerHTML — convenient for a display-only fragment, wrong for anything interactive, since everything inside is destroyed and rebuilt on every update. See reactive.
reactive.BindTempl(preview, func() templ.Component {
return views.Markdown(source.Get())
})
// Convenient for a display-only panel that changes as a unit. Wrong for
// anything interactive: templ produces a string, so everything inside
// preview is destroyed and rebuilt — losing focus, scroll and selection.Why BindTempl loses state
The component renders to a string, and the string is assigned as innerHTML — there is nothing to patch against, so the whole subtree is replaced and focus, scroll and selection go with the old nodes.
For layouts, an SEO head and an RSS feed ready to copy in, see Starter templates.