web.md

 1# Go web apps
 2
 3Read [../web.md](../web.md), [baseline.md](baseline.md), [mise.md](mise.md),
 4[testing.md](testing.md), and [preferred-libraries.md](preferred-libraries.md)
 5before applying these Go web specifics.
 6
 7Default to a light server-rendered stack unless the product is clearly
 8frontend-heavy.
 9
10## Default light web stack
11
12- `net/http`
13- `html/template` or `text/template` as appropriate
14- `embed.FS` for templates and static assets
15- plain CSS with semantic variables
16- semantic HTML forms and links before client-side JavaScript
17- small Node toolchain only for things like Prettier/template formatting when
18  needed
19
20This is the default for admin panels, dashboards, release trackers, internal
21tools, and server-rendered apps with modest interaction.
22
23## Light web layout
24
25```text
26cmd/<app>/main.go
27internal/config/...
28internal/db/...
29internal/<domain>/...
30internal/web/ or web/
31├── handler.go
32└── static/
33    ├── head.html.tmpl
34    ├── page.html.tmpl
35    ├── styles.css
36    └── reset.css
37```
38
39Use `template.ParseFS` with named shared templates. Keep handlers thin: parse
40input, call domain code, render or redirect.
41
42## Security
43
44- Treat form/query values as untrusted.
45- Use `bluemonday` when rendering user-provided HTML or Markdown-derived HTML.
46- Keep auth/session logic in a domain package; handlers should not duplicate
47  password or token handling.
48- Prefer `database/sql` with explicit migrations for small SQLite-backed apps.
49
50## Escalate to frontend-heavy only when needed
51
52Escalate to a frontend-heavy stack only when the UI needs rich local state,
53complex component composition, desktop integration, drag/drop, long-running event
54streams, or substantial client-side interaction. For Wails, prefer Svelte 5 +
55TypeScript + Vite; Tailwind and shadcn-svelte remain explicit project choices.
56If the page can remain a form and a template, keep it light.