Add conflict resolution diff UI and app branding
This commit is contained in:
67
.project/adrs/adr-003-ssr-strategy.md
Normal file
67
.project/adrs/adr-003-ssr-strategy.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# ADR-003: SSR Strategy - Go Templates with Preact Hydration
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
The application needs to serve document pages that are readable without JavaScript (for performance and accessibility), while providing rich interactivity (comments, editing, search) when JavaScript is available. We need a server-side rendering strategy that works with our Go backend and Preact frontend.
|
||||
|
||||
## Decision
|
||||
**Strategy C**: Go's `html/template` renders initial HTML for all pages. Preact hydrates interactive components on the client.
|
||||
|
||||
### Implementation Details
|
||||
|
||||
1. **Server Rendering**:
|
||||
- Go handlers query database for document content
|
||||
- Markdown parsed to HTML server-side (Goldmark)
|
||||
- `html/template` renders full page with document HTML embedded
|
||||
- No JavaScript required for reading
|
||||
|
||||
2. **Client Hydration**:
|
||||
- Preact components mount into designated DOM containers
|
||||
- Comments, search, editor are Preact islands
|
||||
- Static content remains server-rendered HTML
|
||||
- `preact-iso` handles client-side navigation between pages
|
||||
|
||||
3. **Data Passing**:
|
||||
- Initial state embedded as JSON in `<script type="application/json">` tags
|
||||
- Preact reads initial state during hydration, avoids extra API calls
|
||||
- CSP nonce applied to all inline scripts
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
- First contentful paint is instant (pure HTML)
|
||||
- SEO-friendly without extra complexity
|
||||
- Graceful degradation: works without JS
|
||||
- Go templates are auto-escaping XSS-safe
|
||||
- No V8/JS runtime embedded in Go binary
|
||||
- Smaller client bundle (only interactive components)
|
||||
|
||||
### Negative
|
||||
- Some code duplication: markdown parsing logic in both Go and JS (for preview)
|
||||
- Template syntax is verbose compared to JSX
|
||||
- Hydration can cause flicker if not carefully managed
|
||||
- Client state must reconcile with server-rendered HTML
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Go Templates Only (No Preact)
|
||||
- **Pros**: Zero client JS, maximum performance
|
||||
- **Cons**: No interactive features (comments, real-time sync, search)
|
||||
- **Rejected**: Doesn't meet collaboration requirements
|
||||
|
||||
### Embedded JS Runtime (QuickJS/V8)
|
||||
- **Pros**: True isomorphic rendering, JSX templates
|
||||
- **Cons**: Adds C dependency, complex build, larger binary, security surface area
|
||||
- **Rejected**: Violates minimal dependency principle
|
||||
|
||||
### Preact SSR via WASM
|
||||
- **Pros**: Same templates on server and client
|
||||
- **Cons**: WASM overhead, complex build pipeline, slower than Go templates
|
||||
- **Rejected**: Go templates are faster and simpler
|
||||
|
||||
## References
|
||||
- Go html/template security: https://pkg.go.dev/html/template
|
||||
- Preact hydration: https://preactjs.com/guide/v10/server-side-rendering
|
||||
- Islands Architecture: https://jasonformat.com/islands-architecture/
|
||||
Reference in New Issue
Block a user