diff --git a/.skills/htmx-alpine-integration.md b/.skills/htmx-alpine-integration.md new file mode 100644 index 0000000..35cd096 --- /dev/null +++ b/.skills/htmx-alpine-integration.md @@ -0,0 +1,82 @@ +# HTMX + Alpine.js Integration Pattern + +## Problem: "Alpine Expression Error: [variable] is not defined" + +When HTMX swaps in content containing Alpine.js directives (like `x-show`, `x-if`, `@click`), Alpine may not automatically process the new DOM elements, resulting in console errors like: + +``` +Alpine Expression Error: activeTab is not defined +Expression: "activeTab === 'brews'" +``` + +## Root Cause + +HTMX loads and swaps content into the DOM after Alpine has already initialized. The new elements contain Alpine directives that reference variables in a parent Alpine component's scope, but Alpine doesn't automatically bind these new elements to the existing component. + +## Solution + +Use HTMX's `hx-on::after-swap` event to manually tell Alpine to initialize the new DOM tree: + +```html +
+
+``` + +### Key Points + +- `hx-on::after-swap` - HTMX event that fires after content swap completes +- `Alpine.initTree($el)` - Tells Alpine to process all directives in the swapped element +- `$el` - HTMX provides this as the target element that received the swap + +## Common Scenario + +**Parent template** (defines Alpine scope): +```html +
+ + + + +
+
+
+``` + +**Loaded partial** (uses parent scope): +```html +
+ +
+
+ +
+``` + +Without `Alpine.initTree($el)`, the `x-show` directives won't be bound to the parent's `activeTab` variable. + +## Alternative: Alpine Morph Plugin + +For more complex scenarios with nested Alpine components, use the Alpine Morph plugin: + +```html + +
+``` + +This preserves Alpine state during swaps but requires the plugin. + +## When to Use + +Apply this pattern whenever: +1. HTMX loads content containing Alpine directives +2. The loaded content references variables from a parent Alpine component +3. You see "Expression Error: [variable] is not defined" in console +4. Alpine directives in HTMX-loaded content don't work (no reactivity, clicks ignored, etc.) diff --git a/justfile b/justfile index 9b468fb..b458417 100644 --- a/justfile +++ b/justfile @@ -1,11 +1,8 @@ run: - @LOG_LEVEL=debug LOG_FORMAT=console go run cmd/server/main.go + @LOG_LEVEL=debug LOG_FORMAT=console go run cmd/server/main.go -firehose run-production: - @LOG_FORMAT=json SECURE_COOKIES=true go run cmd/server/main.go - -run-firehose: - @LOG_LEVEL=debug LOG_FORMAT=console go run cmd/server/main.go -firehose + @LOG_FORMAT=json SECURE_COOKIES=true go run cmd/server/main.go -firehose test: @go test ./... -cover -coverprofile=cover.out diff --git a/templates/profile.tmpl b/templates/profile.tmpl index 30a8aa8..8542c39 100644 --- a/templates/profile.tmpl +++ b/templates/profile.tmpl @@ -87,7 +87,7 @@ -
+