Templ
Overview
Templ provides type-safe HTML templates that are compiled to Go code. Lemmego includes a templ package that bridges Templ components with the framework’s rendering pipeline.
Setup
The generated project includes Templ support out of the box. If you selected Templ as your frontend during lemmego new, the necessary files and configuration are already in place.
Rendering a Templ Component
import "github.com/lemmego/templ"
func MyHandler(c app.Context) error {
return c.Templ(components.Hello("World"))
}Or using the package-level helper:
return templ.Respond(c, components.Hello("World"))TemplResponse
The TemplResponse type implements the Renderer interface, enabling it to be used with c.Render():
response := templ.New(c, components.Page(data))
return c.Render(response)How It Works
templ.New(ctx, component)creates aTemplResponsewrapping atempl.Component- On render, it sets
Content-Type: text/html, writes the HTTP status code, then callscomponent.Render(ctx.RequestContext(), w)
Template Sources
Templ source files are located in templates/:
templates/
├── base-layout.templ # Base layout component
├── index.templ # Index page component
├── method.templ # Method override helper
└── csrf.templ # CSRF token helperThe generated _templ.go files (compiled from .templ) should not be edited directly.
Development Workflow
During development, run Templ in watch mode:
lemmego devThis starts templ generate --watch alongside air, so changes to .templ files are automatically recompiled and the server reloads.
Example Component
// templates/hello.templ
package components
templ Hello(name string) {
<div class="greeting">
<h1>Hello, { name }!</h1>
</div>
}Usage in a handler:
func HelloHandler(c app.Context) error {
return c.Templ(components.Hello(c.Query("name")))
}CSRF and Method Helpers
The generated project includes Templ helpers for CSRF tokens and method override:
templ CsrfField() {
<input type="hidden" name="_token" value={ templ.Raw(csrf.Token) }/>
}
templ MethodField(method string) {
<input type="hidden" name="_method" value={ method }/>
}Usage in forms:
templ EditForm(task models.Task) {
<form method="POST" action={ templ.URL("/tasks/" + strconv.Itoa(task.ID)) }>
@MethodField("PUT")
@CsrfField()
<input type="text" name="title" value={ task.Title }/>
<button type="submit">Update</button>
</form>
}