Templates & Frontend¶
GoForge uses templ for type-safe server-side templates and HTMX 2 for dynamic UI interactions.
Template Structure¶
internal/web/templates/
├── layouts/
│ └── base.templ # HTML shell with sidebar, nav, scripts
├── pages/
│ ├── dashboard.templ # Dashboard with stats cards
│ ├── login.templ # Login form
│ ├── register.templ # Registration form
│ ├── projects/ # Project list and detail views
│ ├── deployments/ # Deployment views
│ ├── services/ # Service catalog and instances
│ ├── settings/ # User settings
│ └── errors/ # Error pages (404, 500)
└── components/
├── sidebar.templ # Navigation sidebar
├── nav.templ # Top navigation bar
├── form.templ # Reusable form elements
├── modal.templ # Modal dialogs
├── toast.templ # Toast notifications
└── ...
Working with templ¶
Generating Templates¶
The make dev command handles this automatically via air.
Template Syntax¶
templ templates are Go files with HTML-like syntax:
package pages
import "github.com/raythurman2386/goforge/internal/models"
templ ProjectList(projects []*models.Project) {
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
for _, p := range projects {
<div class="card">
<h3>{ p.Name }</h3>
<p>{ p.Description }</p>
</div>
}
</div>
}
Type Safety¶
templ provides compile-time type checking:
- Template parameters are strongly typed
- Go expressions are validated at compile time
- Component composition is checked for correct argument types
Generated Files¶
templ generates *_templ.go files next to each .templ file. These are:
- Excluded from version control (
.gitignore) - Excluded from linting (
.golangci.yml) - Regenerated by
make templormake build
HTMX Integration¶
HTMX enables dynamic UI without writing JavaScript. Common patterns used in GoForge:
Partial Page Updates¶
<button hx-post="/projects/{id}/deploy"
hx-target="#deployment-status"
hx-swap="innerHTML">
Deploy
</button>
Form Submissions¶
<form hx-post="/projects"
hx-target="#project-list"
hx-swap="afterbegin">
<!-- form fields -->
</form>
Server-Sent Events¶
<div hx-ext="sse"
sse-connect="/sse/deployments/{id}/logs"
sse-swap="message">
<!-- Logs appear here in real-time -->
</div>
CSRF Token¶
The base template configures HTMX to send the CSRF token automatically:
TailwindCSS¶
GoForge uses TailwindCSS for styling.
Building CSS¶
Configuration¶
The Tailwind configuration is in tailwind.config.js:
- Scans
.templand generated_templ.gofiles for class names - Uses a green/emerald color palette
- Includes custom font families
Input and Output¶
- Input:
static/css/input.css(Tailwind directives) - Output:
static/css/output.css(generated, not committed)
Adding a New Page¶
- Create the templ template in
internal/web/templates/pages/:
// internal/web/templates/pages/newpage.templ
package pages
templ NewPage(data SomeData) {
@layouts.Base("Page Title") {
<h1>New Page</h1>
// page content
}
}
- Create or update the handler in
internal/web/handlers/:
func (h *Handler) NewPage(w http.ResponseWriter, r *http.Request) {
data := h.service.GetData(r.Context())
pages.NewPage(data).Render(r.Context(), w)
}
- Add the route in
internal/web/router.go:
- Regenerate templates: