Getting Started
Core Concepts
Control
Interactivity
Pushing Data
HTMX Extensions
Miscellaneous
Configuration
Alpine Compat
The alpine-compat extension preserves Alpine.js
state across htmx swaps, re-runs Alpine init on swapped-in
content, and round-trips Alpine component state through
htmx's history cache. It ships inside
/public/htmgo.js and auto-gates on
window.Alpine — if you don't load Alpine, the
extension no-ops.
Loading Alpine alongside htmgo:
1h.Html(
2 h.Head(
3 // Alpine v3.15.11 — tested pin. Use [email protected] for patch updates.
4 h.Tag("script",
5 h.Attribute("src", "https://unpkg.com/[email protected]/dist/cdn.min.js"),
6 h.Attribute("defer", ""),
7 ),
8 h.Script("/public/htmgo.js"),
9 ),
10)Prevent FOUC for x-cloak:
Add this CSS rule so x-cloak-marked elements stay hidden until Alpine initializes them:
1[x-cloak] { display: none !important; }Using the ax package:
htmgo's framework/ax package mirrors the
hx shape with Alpine directive helpers. Common
helpers: ax.Data, ax.Show,
ax.OnClick, ax.Model,
ax.BindClass, ax.OnKeydownEscape,
ax.Cloak. See GoDoc for the full list.
1h.Div(
2 h.Class("relative"),
3 ax.Data("{ open: false }"),
4
5 h.Button(
6 h.Class("btn"),
7 ax.OnClick("open = !open"),
8 h.Text("Toggle"),
9 ),
10
11 h.Div(
12 h.Class("popover"),
13 ax.Show("open"),
14 ax.Cloak(),
15 ax.OnClickOutside("open = false"),
16 ax.OnKeydownEscape("open = false"),
17 h.HxGet("/popover/content"),
18 h.HxTrigger("intersect once"),
19 h.HxSwap(hx.SwapTypeInnerHtml),
20 h.Text("Loading…"),
21 ),
22)Alpine + htmx swap interaction:
When htmx morphs content into an Alpine component's
descendant, the extension's
htmx_before_morph_node hook copies
_x_dataStack to the new nodes and
Alpine.cloneNode preserves bindings. State
survives the swap. When htmx morphs the Alpine root itself,
the extension still carries state through because it runs
before htmx's morph op.
Gotchas: