HTMX swaps
A component inside an HTMX target is removed and re-created by a swap. The new instance is fully interactive, and the old one has cleaned up after itself.
What the component guarantees
Section titled “What the component guarantees”connectedCallbackregisters its listeners, observers and timers;disconnectedCallbackremoves every one it added.- Re-connection after a swap produces exactly one active set of listeners — not two, not none.
- No global state is created on
window, and no timer survives a disconnect. An element removed mid-animation does not keep ticking. - Focus is not stolen by any component after a swap. Restoring focus is the host’s decision, because only the host knows what the swap was for.
<div id="results" hx-get="/racers" hx-trigger="every 5s" hx-swap="innerHTML"> <hui-table>…</hui-table></div>A dialog or popover mid-swap
Section titled “A dialog or popover mid-swap”An overlay left in the browser’s top layer after its host element has gone would keep the page inert with nothing to dismiss. Each overlay closes itself on disconnectedCallback, so an hx-swap that removes an open dialog or popover leaves the page usable.
If the open overlay’s own trigger is inside the region being swapped, focus is restored to an element that no longer exists; the shared focus helper falls back to a sensible target rather than throwing. If you need focus to land somewhere specific after a swap, move it yourself in an htmx:afterSwap handler.
Interactive example
Section titled “Interactive example”The preview below is two independent instances. Because previews run in an iframe with only the library loaded — no HTMX — a real hx-swap cannot be demonstrated here. What it shows is the shape: a comfortable target that a swap would replace wholesale, with no wrapper element of Home-UI’s own in the way.
Source
<div style="display:flex;flex-direction:column;gap:.5rem;width:100%"><hui-input name="q" placeholder="Search racers" aria-label="Search racers"></hui-input><div style="display:flex;gap:.5rem"> <hui-button size="sm">All</hui-button> <hui-button size="sm" variant="ghost">Seniors</hui-button> <hui-button size="sm" variant="ghost">Veterans</hui-button></div></div>The library’s integration suite proves the lifecycle claims above against the real thing: a component re-created by hx-swap stays interactive and fires its event exactly once, including after a second swap (tests/integration/htmx-swap.spec.ts).