Interop
gsx.Node and templ.Component share the same Render(context.Context, io.Writer) error method, so they work together without an adapter. For help choosing a template system, see Comparisons.
templ
Render gsx from templ
Call a gsx component directly from a .templ file:
import "github.com/gsxhq/gsx"
component Card(title string, children gsx.Node) {
<article><h2>{title}</h2>{children}</article>
}templ Page() {
@views.Card("Welcome", nil)
}views.Card retains its authored Go signature and returns a gsx.Node, which also satisfies templ.Component.
Render templ from gsx
Accept a gsx.Node, then pass a templ component to it:
component Shell(body gsx.Node) {
<main>{body}</main>
}page := views.Shell(templComponent) // templComponent is a templ.ComponentThe templ component satisfies gsx.Node structurally and renders in place.
Children stay explicit
templ passes block children through context.Context; gsx receives children through an explicit lowercase children gsx.Node parameter. Pass the child value directly:
templ Child() {
<p>Child</p>
}
templ Page() {
@views.Card("Welcome", Child())
}Do not use templ's @views.Card(...) { ... } block form for a gsx component: gsx does not read templ.GetChildren from the context.
html/template
Render gsx into a template
Render the node, then pass the complete result as template.HTML:
var body bytes.Buffer
if err := views.Page(props).Render(ctx, &body); err != nil {
return err
}
return tmpl.Execute(w, struct{ Body template.HTML }{
Body: template.HTML(body.String()),
})Bind the Go template's Body field where the rendered node should appear. This conversion crosses a trust boundary: wrap only rendered output you trust, never an unvalidated string.
Render a template into gsx
Render the template, then pass the complete result through gsx.Raw:
var body bytes.Buffer
if err := tmpl.Execute(&body, data); err != nil {
return err
}
return views.Shell(gsx.Raw(body.String())).Render(ctx, w)gsx.Raw bypasses HTML escaping. Use it only for output produced by a trusted html/template, never for unvalidated input.
Client-side islands
Render the server-owned shell and serialized data with gsx, then load the client bundle that mounts or hydrates the island:
component ChartIsland(data ChartData) {
<div id="chart"></div>
<script type="application/json" id="chart-data">@{data}</script>
<script type="module" src="/assets/chart.js"></script>
}See JavaScript for JSON data islands and script interpolation.