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

FeatureStandard HTMXhx-boost
HTML changes requiredAdd attributes to each elementOne attribute on a container
Target of swapAny element you specifyAlways the <body> (or hx-target)
Works without JavaScriptNo (falls back to no action)Yes (falls back to full navigation)
URL managementRequires hx-push-urlAutomatic (pushes URL always)
Best forGranular, component-level updatesSpeeding 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.

Leave a Comment

Your email address will not be published. Required fields are marked *