5.1 KiB
5.1 KiB
AGENTS.md - Nebula Project Guidelines
Project Overview
Nebula is a Go/Templ wallet application with HTMX 4 for server-driven UI and WebAwesome (wa-*) web components.
Stack: Go 1.25+ | templ v0.3.977 | htmx 4.0.0-alpha5 | WebAwesome | SQLite WASM
Build & Run Commands
# Generate Go code from .templ files (REQUIRED after any .templ changes)
templ generate
# Build the project
go build ./...
# Run development server (serves on :8080)
go run main.go
# Watch mode for templ files
templ generate --watch
# Full build + run + open browser
make all
Directory Structure
nebula/
├── models/ # Data types (MVC models)
├── views/ # Page templates (.templ)
├── layouts/ # Base layouts (DashboardLayout, CenteredLayout)
├── components/ # Reusable UI components
├── handlers/ # HTTP route handlers
├── _migrate/ # HTML prototypes to convert
├── HTMX.md # htmx 4 patterns documentation
└── SQLC.md # Database schema documentation
Code Style
Go Files
- Standard
gofmtformatting - Package-level types in
models/directory - Handlers in
handlers/routes.gowith pattern:handleX(w http.ResponseWriter, r *http.Request) - Use
r.Header.Get("HX-Request") == "true"to detect HTMX requests - Return partials for HTMX, full pages for direct navigation
Templ Files (.templ)
- One main page template per file:
PageName(data ModelType) templ.Component - Helper functions lowercase:
helperName() - CSS-in-templ using
templ cssblocks or<style>tags - Component parameters use Go types from
models/package
Naming Conventions
| Type | Convention | Example |
|---|---|---|
| Page template | XxxPage |
SettingsPage, DashboardPage |
| Partial template | XxxContent, XxxTab |
DashboardContent, ProfileTab |
| OOB update | XxxWithOOB, XxxWithStepper |
LoginStepWithOOB |
| Model struct | PascalCase | SettingsData, ProfileSettings |
| Handler func | handleXxx |
handleSettings, handleDashboard |
HTMX 4 Patterns
Partial Updates
<div hx-get="/endpoint" hx-target="#target" hx-swap="innerHTML">
Out-of-Band Updates
templ ComponentWithOOB() {
@MainContent()
<div id="sidebar" hx-swap-oob="true">
@UpdatedSidebar()
</div>
}
HTMX Request Detection
if r.Header.Get("HX-Request") == "true" {
views.PartialContent(data).Render(r.Context(), w)
return
}
views.FullPage(data).Render(r.Context(), w)
WebAwesome Components
Use wa-* web components for UI:
<wa-button variant="brand">Click me</wa-button>
<wa-card>Content</wa-card>
<wa-tab-group>
<wa-tab panel="one">Tab 1</wa-tab>
<wa-tab-panel name="one">Panel 1</wa-tab-panel>
</wa-tab-group>
<wa-icon name="user"></wa-icon>
<wa-avatar initials="JD"></wa-avatar>
Route Registration
All routes in handlers/routes.go:
func RegisterRoutes(mux *http.ServeMux) {
mux.HandleFunc("GET /path", handlePath)
mux.HandleFunc("POST /path/action", handleAction)
}
Go 1.22+ routing patterns:
GET /path- method prefixGET /path/{param}- path parameters viar.PathValue("param")GET /path/{param...}- catch-all
Model Pattern
Models in models/ package with DefaultXxxData() factory functions:
// models/example.go
package models
type ExampleData struct {
Field1 string
Field2 int
Items []Item
}
func DefaultExampleData() ExampleData {
return ExampleData{
Field1: "default",
Items: []Item{...},
}
}
Migration Pattern (HTML to Templ)
When converting _migrate/*.html files:
- Create model types in
models/xxx.go - Create view in
views/xxx.templ - Add route in
handlers/routes.go - Update sidebar active state in
components/sidebar.templ
Templ Syntax Reference
// Conditionals
if condition {
<div>shown</div>
}
// Loops
for _, item := range items {
<div>{ item.Name }</div>
}
// Boolean attributes
<input disabled?={ isDisabled } />
<wa-tab active?={ tab == "profile" }>
// String interpolation
<div class={ "base " + extraClass }>
<div data-id={ item.ID }>
// Raw HTML (use sparingly)
@templ.Raw(htmlString)
// Component composition
@ChildComponent(props)
Testing
# Run all tests
go test ./...
# Run with verbose
go test -v ./...
# Run specific package
go test ./handlers/...
Common Tasks
Add New Page
- Create
models/newpage.gowith data types - Create
views/newpage.templwith page template - Add handler in
handlers/routes.go - Add nav item in
components/sidebar.templif needed
Add New Component
- Create in
components/newcomp.templ - Import in views:
import "nebula/components" - Use:
@components.NewComp(props)
Modify Layout
Layouts in layouts/:
base.templ- HTML document wrapper with htmx CDNapp.templ- Dashboard app shell with sidebarcentered.templ- Centered auth pages
Dependencies
- templ: Template engine -
go install github.com/a-h/templ/cmd/templ@latest - htmx 4: Loaded from CDN in
layouts/base.templ - WebAwesome: Loaded from CDN in
layouts/base.templ