Templates
Type-safe HTML with Templ.
HAMR uses Templ for views. Templ compiles .templ files into Go code, giving you compile-time errors, full IDE autocomplete, and zero runtime template parsing.
A basic component
package books
import (
"github.com/labstack/echo/v4"
"github.com/yourname/myapp/internal/web/components"
"github.com/yourname/myapp/internal/repo"
)
templ listPage(c echo.Context, books []repo.Book) {
@components.Layout(c, "Books") {
<main class="max-w-4xl mx-auto px-6 py-12">
<h1 class="text-3xl font-bold mb-6">Books</h1>
<ul class="space-y-2">
for _, book := range books {
<li class="p-4 rounded border">
<a href={ templ.SafeURL("/books/" + book.ID) }>
{ book.Title }
</a>
</li>
}
</ul>
</main>
}
}Templ components are just Go functions. They take typed parameters, can call each other, and pass children blocks via children syntax.
Layouts
Every HAMR project ships with a components/layout.templ base layout. Pages call @components.Layout(c, title) and pass their content as a child block.
package components
import "github.com/labstack/echo/v4"
templ Layout(c echo.Context, title string) {
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8"/>
<title>{ title } — My App</title>
<link rel="stylesheet" href={ StaticURL("css/output.css") }/>
</head>
<body class="bg-slate-900 text-slate-200">
{ children... }
<script src={ StaticURL("js/htmx.min.js") }></script>
<script src={ StaticURL("js/alpine.min.js") } defer></script>
</body>
</html>
}Static URL helper
Use components.StaticURL(path) to reference static assets. It prepends STATIC_BASE_URL (handy for CDN hosting) and appends a cache-busting version query string set from the build's git commit.
<link rel="stylesheet" href={ components.StaticURL("css/output.css") }/>
<script src={ components.StaticURL("js/htmx.min.js") }></script>Rendering from a handler
Render Templ components with respond.HTML. It handles content negotiation: if the request is HTML (browser or HTMX), it renders the component; if the client wants JSON, it returns an error.
func (h *handler) Index(c echo.Context) error {
return respond.HTML(c, http.StatusOK, listPage(c, books))
}Generating Go code
Templ files are compiled to Go via templ generate. The HAMR dev server runs this automatically on file change. You can also run it manually:
templ generate