HTMX hx-boost
The hx-boost attribute is HTMX's progressive enhancement tool. It intercepts ordinary HTML links and form submissions and converts them into HTMX requests that update the page body without a full reload. You add one attribute to a container element, and every link and form inside it instantly becomes HTMX-powered — with no other changes to your HTML.
What hx-boost Does
BEFORE hx-boost:
User clicks a link → full page reload → browser re-renders everything
AFTER hx-boost:
User clicks a link → HTMX sends GET request
→ server returns full page HTML
→ HTMX extracts the <body> content
→ replaces current body without reload
→ URL updates in browser history
The user experience feels like a single-page application. Navigation is instant because the browser does not repaint headers, footers, or sidebars from scratch — only the body content changes.
Basic Usage
<body hx-boost="true">
<nav>
<a href="/home">Home</a>
<a href="/about">About</a>
<a href="/products">Products</a>
<a href="/contact">Contact</a>
</nav>
<main>
<!-- All standard links and forms boosted automatically -->
</main>
</body>
With hx-boost="true" on the <body>, every link click and form submit in the entire page becomes an HTMX request. The links remain standard <href> links — they still work without JavaScript (progressive enhancement).
hx-boost Inherits Down the DOM
HTMX attributes inherit from parent to child elements. Setting hx-boost="true" on the body affects every descendant. You can selectively disable boosting on specific links with hx-boost="false":
<body hx-boost="true">
<nav>
<a href="/home">Home</a> <!-- boosted -->
<a href="/about">About</a> <!-- boosted -->
<a href="/external" hx-boost="false">
External Site
</a> <!-- NOT boosted → full navigation -->
</nav>
</body>
How hx-boost Compares to Standard HTMX
| Feature | Standard HTMX | hx-boost |
|---|---|---|
| HTML changes required | Add attributes to each element | One attribute on a container |
| Target of swap | Any element you specify | Always the <body> (or hx-target) |
| Works without JavaScript | No (falls back to no action) | Yes (falls back to full navigation) |
| URL management | Requires hx-push-url | Automatic (pushes URL always) |
| Best for | Granular, component-level updates | Speeding up traditional multi-page sites |
hx-boost and Boosted Request Headers
Boosted requests include the header HX-Boosted: true in addition to the usual HX-Request: true. The server can detect a boost and respond with just the content portion of the page if desired, though HTMX can extract the body content from a full page response on its own.
# Flask: detect boost and return optimized response
@app.route('/products')
def products():
is_boosted = request.headers.get('HX-Boosted') == 'true'
is_htmx = request.headers.get('HX-Request') == 'true'
context = {'products': get_products()}
if is_htmx and is_boosted:
# Return only the body content — faster, smaller payload
return render_template('partials/products_body.html', **context)
else:
return render_template('products.html', **context)
Boosting Forms
Boosted forms send POST requests via HTMX and replace the body with the response. The server typically redirects after a successful form submission, and HTMX follows that redirect as another boosted request:
<body hx-boost="true">
<form action="/login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<button type="submit">Log In</button>
</form>
</body>
Flow:
User submits login form
↓
HTMX intercepts submit, sends POST /login (boosted)
↓
Server validates credentials
↓
Server redirects to /dashboard (302 response)
↓
HTMX follows redirect, sends GET /dashboard (boosted)
↓
Dashboard body loads into current page — no full reload
Script and Style Handling With hx-boost
HTMX handles <script> and <link> tags in boosted responses carefully:
- New
<script>tags in the response body are executed after the swap. - Scripts already present in the current page are not re-executed (preventing duplicate initialization).
- New
<link>stylesheets are loaded before the swap completes to prevent unstyled flashes.
If a third-party library needs to re-initialize after a boost, listen for htmx:afterSwap as usual.
Adding a Progress Bar for Boost Navigation
A thin progress bar at the top of the page during boosted navigation improves perceived performance:
<style>
#progress-bar {
position: fixed; top: 0; left: 0;
height: 3px; width: 0;
background: #4a90d9;
transition: width 0.3s ease;
display: none;
}
body.htmx-request #progress-bar {
display: block;
width: 50%;
}
</style>
<div id="progress-bar"></div>
<script>
htmx.on('htmx:afterSwap', () => {
const bar = document.getElementById('progress-bar');
bar.style.width = '100%';
setTimeout(() => { bar.style.width = '0'; bar.style.display = 'none'; }, 400);
});
</script>
Key Takeaway
The hx-boost="true" attribute converts every standard link and form inside its container into an HTMX-powered request that replaces the page body without a full reload. Add it once to the <body> and your entire site navigation becomes SPA-like. Links remain functional without JavaScript — they fall back to full page navigation. Disable boosting on specific links with hx-boost="false". Detect boost requests on the server using the HX-Boosted header to return optimized, partial responses.
