htmx swaps HTML fragments in from the server on its own schedule. Below, every swapped-in fragment contains a live WildflowerJS component. The verification log at the bottom records, in real time, whether the claims below actually hold — not a staged result.
Click to fetch fragments/order-form.html and swap it into
the empty slot below (a deliberately slow 150ms swap + 150ms settle, to give any
timing race the best chance of showing up). The form has real client-side state:
a computed total, and a submit button that carries both an hx-get
attribute (htmx's) and a data-bind-attr attribute (WildflowerJS's)
on the same element.
hx-boost intercepts this link, fetches the target page,
and swaps the <body> in place instead of a full page load. The target page
has its own WildflowerJS component that has never existed on this page before.
wildflower.scan() call anywhere in this demo)hx-get and data-bind-attr coexist on one element<button hx-get="fragments/order-form.html"
hx-target="#order-slot"
hx-swap="innerHTML">
Load order form
</button>
<div id="order-slot"></div>
<!-- fragments/order-form.html -->
<div data-component="order-form">
<input data-model="qty">
<input data-model="price">
<span data-bind="total"></span>
<button data-bind-attr="{ disabled: overBudget }"
hx-get="fragments/confirmation.html"
hx-target="#order-slot">
Place order
</button>
</div>
// Registered once, up front. htmx swaps markup; it never needs to know
// this component exists. WildflowerJS's mutation observer does the rest.
wildflower.component('order-form', {
state: { qty: 2, price: 15, budget: 100 },
computed: {
total() { return this.qty * this.price; },
overBudget() { return this.total > this.budget; }
}
});