Update a Header from a Modal with htmx’s Out‑of‑Band Swap
Learn how htmx’s hx‑swap‑oob lets a server push UI changes to any element on the page, even from a modal dialog, without a full reload. See a step‑by‑step example, trade‑offs, and how to verify the swap works in real browsers.
30 Nov 2025, 14:37 UTC

Problem
When a modal dialog submits a form, you often want the page to reflect a change—say, updating a navigation bar or a notification area—without reloading the whole page. A naive approach is to return a full page from the server and replace the entire body, which defeats the purpose of a modal. Alternatively, you could use JavaScript to manually patch the DOM after the modal closes, but that requires duplicating logic on the client and can become brittle.
htmx’s hx-swap-oob attribute solves this by letting the server send a fragment that the browser automatically inserts into any target element, even if that element was not part of the original request.
Out‑of‑Band Swaps Explained
When a response contains an element with hx-swap-oob="true", htmx treats it as an out‑of‑band fragment. After the response is parsed, htmx looks for the hx-target selector, finds the matching element in the current DOM, and performs the swap defined by hx-swap (default is innerHTML). The swap happens asynchronously after the original request completes, so the user sees the updated UI immediately.
Key points:
- Server can send multiple out‑of‑band fragments in one response.
- Targets are identified by any valid CSS selector.
- The target element must exist in the DOM at the time of the swap.
- Works with any htmx request type (GET, POST, etc.).
Practical Example: Updating the Header from a Modal
Assume we have a page with a header that shows the current user’s name and a modal that lets the user change that name. We want the header to update instantly after the modal form submits.
1. Page Setup
Load htmx (>=1.7.0) and create the header and modal markup.
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/htmx.org@1.9.4/dist/htmx.min.js"></script>
</head>
<body>
<header id="app-header" hx-ext="swap">
<h1>Welcome, Alice</h1>
</header>
<button hx-toggle="modal" hx-target="#name-modal">Change Name</button>
<div id="name-modal" style="display:none;">
<form hx-post="/update-name" hx-trigger="submit">
<label>New name: <input type="text" name="name" required></label>
<button type="submit">Save</button>
</form>
</div>
</body>
</html>
2. Server Response
The server returns an HTML fragment that includes hx-swap-oob="true" and points to the header. For example, after the user submits “Bob”, the server might send:
<div hx-target="#app-header" hx-swap="innerHTML" hx-swap-oob="true">
<h1>Welcome, Bob</h1>
</div>
Because the fragment has hx-swap-oob="true", htmx will locate the element with #app-header and replace its inner HTML with the new content, all without reloading the page.
3. Result
When the form submits, the modal closes (you can add hx-trigger="afterRequest" hx-target="#name-modal" hx-swap="outerHTML" to hide it), and the header updates instantly to “Welcome, Bob”.
Trade‑offs and Limitations
- Element Must Exist: If the target element is not present (e.g., the modal’s parent is removed before the swap), htmx silently fails. Always ensure the element is in the DOM before the request completes.
- Race Conditions: Rapid successive swaps to the same target can interleave unpredictably. If you need strict ordering, trigger a custom event after each swap and queue subsequent updates.
- Bandwidth: Sending full fragments (including
hx-swap-oobattributes) can increase payload size. Prefer server‑side templates that render only the needed fragment. - Browser Support: Requires ES6 support for htmx’s core. Older browsers (IE11) will not execute the swap.
- JavaScript Context: Scripts inside the swapped fragment are not automatically executed. Use
hx-trigger="afterSwap"on the target or manually invokehtmx.processif needed.
How to Verify the Swap Works
- Check htmx Version – In the browser console run
console.log(htmx.version). It should be >= 1.7.0. - Inspect Network Response – Submit the form, open DevTools → Network, click the request, and verify the response contains
hx-swap-oob="true"and the correcthx-target. - Observe the DOM – After the request completes, the header’s inner text should change to the new name without a page reload.
- Cross‑Browser Test – Perform the same steps in Chrome and Firefox to confirm consistent behavior.
- Fallback Check – Disable JavaScript in the browser and ensure the modal still submits to a full page, preserving basic functionality for non‑JS users.
Actionable Takeaway
Use hx-swap-oob when you need to update shared UI components from contexts that are decoupled from the original request—modals, background tasks, or micro‑services responses. It keeps your pages fast, reduces JavaScript boilerplate, and gives you a declarative way to push server‑side changes to the client.
Just remember:
- Target elements must exist.
- Keep payloads lean.
- Test in the browsers you support.
With these checks in place, out‑of‑band swaps become a powerful tool in your htmx toolkit.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.