Out of Band Swaps (hx-swap-oob): Multi-Region Updates from a Single Response
- Last updated
- Prerequisites:
- HTMX hx-swap strategies
- HTML ID uniqueness
- htmx
- hx-swap-oob
- out-of-band
- multi-region
- shopping-cart
- dom
Read at your depth
The practical view
Out of Band Swaps (`hx-swap-oob="true"`) allow a single server response to update multiple disjoint elements on the page. While the main response body is swapped into `hx-target`, any element in the response containing `hx-swap-oob="true" id="some-id"` is automatically swapped into the matching `#some-id` element elsewhere in the DOM.
The same idea in other frameworks
Redux / Context updating multiple connected subscriber components simultaneously.NgRx Store or shared services dispatching updates to multiple components.Pinia store updates triggering multiple reactive template watchers.`<div id="cart-count" hx-swap-oob="true">5</div>` returned in response.Legacy vs modern
Multiple Polling Requests vs Single Response with OOB Swaps
Updating multiple page regions usually requires multiple API calls; OOB swaps update all regions in a single response.
await addToCart(); await updateCartBadge(); await showToast(); // ❌ 3 HTTP roundtrips<div id="cart-badge" hx-swap-oob="true">3</div> // ✅ NEW: Atomic multi-region updateInterview gotchas
Context
Interviewers test your knowledge of OOB matching rules.
The mechanical answer
HTMX **will fail to swap the element** and will log a console error. Out-of-band matching relies strictly on the `id` attribute of the OOB element matching an identical `id` in the active DOM. Without an `id`, HTMX has no identifier to locate the target.
Trap
Always ensure every OOB fragment has an explicit `id="..."` that matches an existing element on the current page.
Context
Checks precision regarding OOB swap value syntax.
The mechanical answer
Yes. Instead of `hx-swap-oob="true"` (which defaults to `outerHTML`), you can specify any swap strategy directly in the attribute: `hx-swap-oob="beforeend"`, `hx-swap-oob="afterbegin"`, `hx-swap-oob="innerHTML"`, or `hx-swap-oob="delete"`.
Trap
`hx-swap-oob="true"` uses `outerHTML` by default, whereas standard `hx-swap` defaults to `innerHTML`.