The March-era page had the right instincts (store state across swaps,
no manual DOM manipulation) but predated the @alpinejs/csp conversion
and never said the load-bearing fact: inline expressions are not
evaluated, so every x-data must reference an Alpine.data component —
which is why the whole attribute value is an expression and why
dynamic arguments go through JSONArg or data-attributes. Rewritten
with the banned list spelled out (inline handlers, hx-on*, js:
hx-vals, stray inline <script>) and each rule tied to the source that
enforces or embodies it (alpine.ts import, header.templ
whole-expression x-data, custom-section-builder data-attribute
pattern, bookPicker store as the living example). Every code sample
verified present in web/src.
Add comprehensive guide for Alpine.js SSR-first patterns in Bookhoard:
- Page classification system (Type 1: 80% SSR, Type 2: SSR+Interactive,
Type 3: 80% TypeScript)
- Alpine.js usage guidelines (UI state only, no data fetching in x-init)
- HTMX integration patterns
- When to use x-show vs CSS classes
- Form handling and validation
- Modal and dropdown patterns
- Component reusability with Alpine.data()
- Alpine.store for global state (book picker example)
This documentation helps developers maintain consistency across the
codebase
and make informed decisions about when to use Alpine.js vs vanilla
JavaScript
vs HTMX for different features.
Follows PROJECT_GUIDELINES.md documentation standards.