docs(alpine): integrate SSR-first principles into Alpine completion guide
Updated ALPINE_COMPLETION_GUIDE.md to reference SSR_FIRST_ALPINE_GUIDE.md and clarify the relationship between all three guides. Changes: - Added reference to SSR_FIRST_ALPINE_GUIDE.md as prerequisite - Added Phase 0: Prerequisites (dead export removal) - Added Phase 3: Other Templates (DOMContentLoaded cleanup) - Reorganized Phase numbers (old Phase 3→4, 4→5, 5→6) - Updated Key Principles section to include SSR-first rules - Added "How This Guide Relates to Others" section (4.3) - Updated Next Steps with recommended reading order - Clarified documentation strategy and goals Key SSR-first additions: - ❌ NEVER fetch data in x-init if data is already SSR'd - ✅ x-init ONLY for setup (event listeners, modals) - ✅ Data fetch ONLY after user actions (create/delete/update) Three Guide Strategy: 1. SSR_FIRST_ALPINE_GUIDE.md - Architecture principles (READ FIRST) 2. COLLECTIONS_CLEANUP_GUIDE.md - Quick reference for immediate fixes 3. ALPINE_COMPLETION_GUIDE.md - Full migration path (this guide) This ensures users understand SSR-first architecture before attempting full Alpine.js migration, preventing common mistakes like fetching data in x-init that replaces SSR content. The guides now work together without contradiction: - SSR_FIRST establishes principles - COLLECTIONS_CLEANUP provides quick fix reference - ALPINE_COMPLETION provides complete migration path Eventually COLLECTIONS_CLEANUP_GUIDE.md can be deprecated once all patterns are understood and incorporated into the other two guides.
This commit is contained in:
+294
-30
@@ -2,36 +2,68 @@
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This guide completes the migration from **hybrid onclick/@click with manual DOM manipulation** to **full reactive Alpine.js** with state-driven UI.
|
||||
This guide completes the migration from **hybrid onclick/@click with manual DOM manipulation** to **full reactive Alpine.js** with state-driven UI, while **maintaining SSR-first architecture**.
|
||||
|
||||
**Current State**: Hybrid approach with 121 manual DOM manipulations
|
||||
**Target State**: Full reactive Alpine.js with zero manual DOM manipulation
|
||||
**Estimated Time**: 10-12 hours
|
||||
**Impact**: Cleaner code, better maintainability, smoother UX
|
||||
|
||||
**References:**
|
||||
- **`SSR_FIRST_ALPINE_GUIDE.md`** - SSR-first architecture principles (READ THIS FIRST)
|
||||
- **`COLLECTIONS_CLEANUP_GUIDE.md`** - Immediate console error fixes (quick reference)
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Current State Analysis](#current-state-analysis)
|
||||
2. [Migration Strategy](#migration-strategy)
|
||||
3. [Phase 1: Header Template (Reference Implementation)](#phase-1-header-template-reference-implementation)
|
||||
4. [Phase 2: Modal Templates](#phase-2-modal-templates)
|
||||
5. [Phase 3: Verification & Testing](#phase-3-verification--testing)
|
||||
6. [Phase 4: Cleanup](#phase-4-cleanup)
|
||||
7. [Troubleshooting](#troubleshooting)
|
||||
8. [Success Criteria](#success-criteria)
|
||||
3. [Phase 0: Prerequisites (Dead Export Removal)](#phase-0-prerequisites-dead-export-removal)
|
||||
4. [Phase 1: Header Template (Reference Implementation)](#phase-1-header-template-reference-implementation)
|
||||
5. [Phase 2: Modal Templates]((#phase-2-modal-templates)
|
||||
6. [Phase 3: Other Templates (DOMContentLoaded Cleanup)](#phase-3-other-templates-domcontentloaded-cleanup)
|
||||
7. [Phase 4: Verification & Testing]((#phase-4-verification--testing)
|
||||
8. [Phase 5: Cleanup]((#phase-5-cleanup)
|
||||
9. [Troubleshooting](#troubleshooting)
|
||||
10. [Success Criteria](#success-criteria)
|
||||
|
||||
---
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### What's Already Done ✅
|
||||
|
||||
- All `onclick` handlers converted to `@click` directives
|
||||
- Functions registered with `Alpine.global()` in TypeScript
|
||||
- 18 templates have `x-data="namespace"` attributes
|
||||
- HTMX integration working for forms
|
||||
- SSR-first architecture documented in `SSR_FIRST_ALPINE_GUIDE.md`
|
||||
|
||||
### Documentation Structure
|
||||
|
||||
**Three complementary guides:**
|
||||
|
||||
1. **`SSR_FIRST_ALPINE_GUIDE.md`** - **READ THIS FIRST**
|
||||
- SSR-first architecture principles
|
||||
- Page type classifications (Type 1: 80% SSR, Type 2: SSR+Interactive, Type 3: 80% JS)
|
||||
- When to fetch data vs when to use SSR data
|
||||
- Server-side token injection
|
||||
- **Prerequisite for understanding this guide**
|
||||
|
||||
2. **`COLLECTIONS_CLEANUP_GUIDE.md`** - Quick reference for immediate fixes
|
||||
- Dead export removal (causes console errors)
|
||||
- DOMContentLoaded cleanup (prevents wrong-page execution)
|
||||
- Step-by-step instructions for common fixes
|
||||
- **Use as reference during this migration**
|
||||
|
||||
3. **`ALPINE_COMPLETION_GUIDE.md`** - **This document**
|
||||
- Full reactive Alpine.js migration path
|
||||
- Eliminate all manual DOM manipulation
|
||||
- Complete code examples and patterns
|
||||
- **Long-term architecture goal**
|
||||
|
||||
### What's Still Missing ❌
|
||||
|
||||
@@ -79,15 +111,22 @@ const toggleThemeDropdown = (): void => {
|
||||
|
||||
### The Pattern
|
||||
|
||||
Every migration follows the same 4-step pattern:
|
||||
|
||||
1. **Template Changes**: Add `x-data` state, replace `class="hidden"` with `x-show`, add transitions
|
||||
2. **TypeScript Cleanup**: Remove manual DOM manipulation functions
|
||||
3. **Alpine Registration**: Remove deleted functions from `Alpine.global()`
|
||||
4. **Testing**: Verify functionality, build, check for regressions
|
||||
Every migration follows the same 5-step pattern:
|
||||
1. **Prerequisites** (Phase 0): Remove dead exports that cause console errors
|
||||
2. **Template Changes**: Add `x-data` state, replace `class="hidden"` with `x-show`, add transitions
|
||||
3. **TypeScript Cleanup**: Remove manual DOM manipulation functions
|
||||
4. **Alpine Registration**: Remove deleted functions from `Alpine.global()` or `Alpine.data()`
|
||||
5. **Testing**: Verify functionality, build, check for regressions
|
||||
|
||||
### Key Principles
|
||||
|
||||
**SSR-First (see `SSR_FIRST_ALPINE_GUIDE.md`):**
|
||||
- ❌ **NEVER fetch data in x-init** if data is already SSR'd
|
||||
- ✅ x-init ONLY for setup (event listeners, modals)
|
||||
- ✅ Data fetch ONLY after user actions (create/delete/update)
|
||||
- ✅ State lives in template (`x-data`), not in TypeScript
|
||||
|
||||
**Alpine.js Best Practices:**
|
||||
- **State lives in template** (`x-data="{ open: false }"`)
|
||||
- **UI updates automatically** (`x-show="open"`)
|
||||
- **No manual DOM manipulation** in TypeScript
|
||||
@@ -95,6 +134,71 @@ Every migration follows the same 4-step pattern:
|
||||
|
||||
---
|
||||
|
||||
## Phase 0: Prerequisites (Dead Export Removal)
|
||||
|
||||
**Before starting full migration**, fix immediate console errors caused by dead Alpine.js exports.
|
||||
|
||||
### Why This Phase?
|
||||
|
||||
When functions are deleted from TypeScript but remain in `Alpine.data()` exports, the browser console shows errors like:
|
||||
- `addbooksToAdd is not defined`
|
||||
- `removebooksToAdd is not defined`
|
||||
- `toggleBookSelection is not defined`
|
||||
|
||||
These must be fixed before attempting full migration.
|
||||
|
||||
### Quick Reference
|
||||
|
||||
For detailed step-by-step instructions, see **`COLLECTIONS_CLEANUP_GUIDE.md`** - **Step 1** covers this process comprehensively.
|
||||
|
||||
### The Process
|
||||
|
||||
**For collections.ts (and similar files):**
|
||||
|
||||
1. **Identify dead exports:**
|
||||
```bash
|
||||
# Check what's exported
|
||||
grep -A25 "Alpine.data" web/src/collections.ts
|
||||
|
||||
# Find actual function definitions
|
||||
grep -n "^function\|^async function" web/src/collections.ts
|
||||
```
|
||||
|
||||
2. **Update export statement:**
|
||||
```typescript
|
||||
// Remove dead functions from export
|
||||
export {
|
||||
// Keep only existing functions
|
||||
backToCollections,
|
||||
closeCollectionModal,
|
||||
// ... etc ...
|
||||
};
|
||||
```
|
||||
|
||||
3. **Update Alpine.data registration:**
|
||||
```typescript
|
||||
Alpine.data("collections", () => ({
|
||||
// Keep only existing functions
|
||||
backToCollections,
|
||||
closeCollectionModal,
|
||||
// ... etc ...
|
||||
}));
|
||||
```
|
||||
|
||||
4. **Verify:**
|
||||
```bash
|
||||
npm run build:ts
|
||||
# Should succeed with 0 errors
|
||||
```
|
||||
|
||||
### Files That Need This Fix
|
||||
|
||||
Based on commit 93710a1 and current errors:
|
||||
- ✅ `web/src/collections.ts` - Already documented in COLLECTIONS_CLEANUP_GUIDE.md
|
||||
- Check other files for similar issues as you encounter them
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Header Template (Reference Implementation)
|
||||
|
||||
**Priority**: P0 (highest - used in 17 templates)
|
||||
@@ -691,7 +795,110 @@ Delete `showConflictModal()`, `hideConflictModal()` functions.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Verification & Testing
|
||||
## Phase 3: Other Templates (DOMContentLoaded Cleanup)
|
||||
|
||||
**Before migrating templates to full reactive Alpine.js**, clean up DOMContentLoaded listeners.
|
||||
|
||||
**See `SSR_FIRST_ALPINE_GUIDE.md`** for complete SSR-first architecture principles.
|
||||
|
||||
### Quick Reference
|
||||
|
||||
For detailed instructions on dashboard, docs, and other pages, see **`COLLECTIONS_CLEANUP_GUIDE.md`** - **Step 3** covers DOMContentLoaded removal.
|
||||
|
||||
### The Pattern
|
||||
|
||||
**Current (WRONG):**
|
||||
```typescript
|
||||
// ❌ Runs on EVERY page (main.ts imports all modules)
|
||||
document.addEventListener("DOMContentLoaded", initializePage);
|
||||
```
|
||||
|
||||
**Solution 1: x-init Wrapper (Current Approach):**
|
||||
```typescript
|
||||
// ✅ Wrap in named function, call via x-init
|
||||
function initializePage() {
|
||||
setupEventListeners();
|
||||
}
|
||||
|
||||
export { initializePage };
|
||||
|
||||
Alpine.data("page", () => ({
|
||||
initializePage,
|
||||
}));
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- Template -->
|
||||
<body x-data="page" x-init="initializePage">
|
||||
```
|
||||
|
||||
**Solution 2: Event Delegation Only (Future Goal):**
|
||||
```typescript
|
||||
// ✅ Rely on global event delegation, no init needed
|
||||
// See ALPINE_COMPLETION_GUIDE.md for full migration path
|
||||
```
|
||||
|
||||
### Files Requiring Cleanup
|
||||
|
||||
**analytics.ts** (Type 3 - 80% JavaScript page):
|
||||
- ✅ Already correct - uses `x-init="loadAnalytics"`
|
||||
- ✅ Data fetch is intentional for this dynamic page
|
||||
|
||||
**docs.ts** (Type 1 - 80% SSR page):
|
||||
- ✅ Remove DOMContentLoaded
|
||||
- ✅ Add `x-init="initializeDocsSearch"` to template
|
||||
- ✅ Simple setup only, no data fetch
|
||||
|
||||
**dashboard.ts** (Type 2 - SSR + Interactive page):
|
||||
- ✅ Wrap existing DOMContentLoaded code in `initDashboard()` function
|
||||
- ✅ Add `x-data="dashboard" x-init="initDashboard"` to template
|
||||
- ✅ Does NOT fetch data on page load (SSR provides initial dashboard)
|
||||
- ✅ Event delegation already in place with `data-action` attributes
|
||||
|
||||
**library.ts** (Type 2 - SSR + Interactive page):
|
||||
- ✅ Already fixed (commit 1b9bc64)
|
||||
- ✅ Removed `reloadLibraries()` from `initializeLibraryAdmin()`
|
||||
- ✅ SSR provides initial library list
|
||||
|
||||
### Implementation Steps
|
||||
|
||||
For each file:
|
||||
|
||||
1. **Remove DOMContentLoaded:**
|
||||
```typescript
|
||||
// DELETE:
|
||||
// document.addEventListener("DOMContentLoaded", initializePage);
|
||||
```
|
||||
|
||||
2. **Export the init function:**
|
||||
```typescript
|
||||
export { initializePage };
|
||||
```
|
||||
|
||||
3. **Add to Alpine.data:**
|
||||
```typescript
|
||||
Alpine.data("page", () => ({
|
||||
initializePage,
|
||||
}));
|
||||
```
|
||||
|
||||
4. **Update template:**
|
||||
```html
|
||||
<!-- BEFORE -->
|
||||
<body class="theme-{ user.Theme }">
|
||||
|
||||
<!-- AFTER -->
|
||||
<body x-data="page" x-init="initializePage" class="theme-{ user.Theme }">
|
||||
```
|
||||
|
||||
5. **Verify SSR-first principles:**
|
||||
- ✅ x-init does NOT fetch data (if Type 1 or Type 2)
|
||||
- ✅ x-init ONLY sets up event listeners
|
||||
- ✅ Data fetch happens only after user actions
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Verification & Testing
|
||||
|
||||
### For Each Migrated Template
|
||||
|
||||
@@ -757,7 +964,7 @@ go run .
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Cleanup
|
||||
## Phase 5: Cleanup
|
||||
|
||||
### 4.1: Remove Unused Functions
|
||||
|
||||
@@ -799,7 +1006,32 @@ Add completion note:
|
||||
- 60% less TypeScript code (header.ts: 100 → 40 lines)
|
||||
```
|
||||
|
||||
### 4.3: Create Migration Documentation
|
||||
### 4.3: How This Guide Relates to Others
|
||||
|
||||
**Three complementary guides:**
|
||||
|
||||
1. **`SSR_FIRST_ALPINE_GUIDE.md`** - **READ THIS FIRST**
|
||||
- SSR-first architecture principles
|
||||
- Page type classifications (Type 1, 2, 3)
|
||||
- When to fetch data (and when NOT to)
|
||||
- Server-side token injection
|
||||
- **Must read before using this guide**
|
||||
|
||||
2. **`COLLECTIONS_CLEANUP_GUIDE.md`** - Quick reference for immediate fixes
|
||||
- Dead export removal (Phase 0 prerequisites)
|
||||
- DOMContentLoaded cleanup (Phase 3)
|
||||
- Template regeneration
|
||||
- Build verification steps
|
||||
- **Use as step-by-step reference**
|
||||
|
||||
3. **`ALPINE_COMPLETION_GUIDE.md`** - **This document**
|
||||
- Full reactive Alpine.js migration
|
||||
- Eliminate all manual DOM manipulation
|
||||
- Header template reference implementation
|
||||
- Modal templates migration
|
||||
- **Long-term architecture goal**
|
||||
|
||||
### 4.4: Create Migration Documentation
|
||||
|
||||
Create `docs/contributing/alpinejs-patterns.md`:
|
||||
|
||||
@@ -1335,20 +1567,52 @@ export { addSelectedBooks, searchBooksForCollections };
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Start with header.templ migration** (highest priority, reference implementation)
|
||||
2. **Apply Alpine.store pattern** to all modal templates
|
||||
3. **Test thoroughly** after each migration
|
||||
4. **Clean up unused functions** from TypeScript files
|
||||
5. **Update documentation** with patterns learned
|
||||
6. **Verify final state**: 0 manual DOM manipulations
|
||||
### Recommended Order
|
||||
|
||||
**Estimated completion time**: 10-12 hours
|
||||
1. **Read `SSR_FIRST_ALPINE_GUIDE.md` first**
|
||||
- Understand SSR-first architecture
|
||||
- Learn page type classifications
|
||||
- Know when to fetch data
|
||||
|
||||
**Success metrics**:
|
||||
- ✅ All 8 templates migrated
|
||||
- ✅ 121 manual DOM manipulations → 0
|
||||
- ✅ All dropdowns/modals use reactive state
|
||||
- ✅ Smooth transitions throughout
|
||||
- ✅ Clean, maintainable codebase
|
||||
2. **Fix immediate console errors** (if needed)
|
||||
- See `COLLECTIONS_CLEANUP_GUIDE.md` Step 1
|
||||
- Remove dead exports
|
||||
- Clean up DOMContentLoaded listeners
|
||||
- Verify builds work
|
||||
|
||||
Good luck with the migration! 🚀
|
||||
3. **Start with header.templ migration** (this guide, Phase 1)
|
||||
- Highest priority (used in 17 templates)
|
||||
- Reference implementation for all other templates
|
||||
- Learn the pattern
|
||||
|
||||
4. **Apply Alpine.store pattern** to modals (this guide, Phase 2)
|
||||
- Collections, conflicts, queue, devices, profile
|
||||
- Consistent modal state management
|
||||
- Remove show/hide functions from TypeScript
|
||||
|
||||
5. **Complete remaining templates** (page-by-page)
|
||||
- Use header.templ as reference
|
||||
- Test thoroughly after each migration
|
||||
- Commit frequently with detailed messages
|
||||
|
||||
6. **Clean up and verify** (this guide, Phase 5)
|
||||
- Remove unused functions
|
||||
- Check for remaining manual DOM manipulation
|
||||
- Update documentation
|
||||
|
||||
### Documentation Strategy
|
||||
|
||||
**Goal:** Eventually deprecate `COLLECTIONS_CLEANUP_GUIDE.md` once all patterns are understood.
|
||||
|
||||
**Current state:**
|
||||
- `SSR_FIRST_ALPINE_GUIDE.md` - Architecture principles (permanent reference)
|
||||
- `ALPINE_COMPLETION_GUIDE.md` - Full migration guide (active use)
|
||||
- `COLLECTIONS_CLEANUP_GUIDE.md` - Step-by-step fixes (quick reference, will be deprecate)
|
||||
|
||||
### Key Success Factors
|
||||
|
||||
- **Follow SSR-first principles** - Don't break SSR with data fetches in x-init
|
||||
- **Test thoroughly** - Each template migration should be verified
|
||||
- **Commit frequently** - Small, focused commits with detailed messages
|
||||
- **Learn the pattern** - Header template is the reference for all others
|
||||
- **Be patient** - This is a 10-12 hour migration across many templates
|
||||
|
||||
Reference in New Issue
Block a user