hx-boost: Progressive Enhancement SPA Anchor and Form Interception
- Last updated
- Prerequisites:
- HTML `<a>` links and `<form>` submissions
- Single Page Application (SPA) mechanics
- htmx
- hx-boost
- progressive-enhancement
- spa
- forms
- navigation
Read at your depth
The practical view
`hx-boost="true"` converts standard HTML links (`<a href="/about">`) and forms (`<form action="/save" method="POST">`) into AJAX requests automatically. It targets the `<body>` element by default, swaps the content, and updates the URL via `pushState`. If JavaScript fails or is disabled, the website continues to work 100% normally via standard browser navigation.
The same idea in other frameworks
Next.js `<Link>` component intercepting client-side route transitions.Angular `routerLink` directive intercepting standard anchor tags.Vue Router `<RouterLink>` component.SvelteKit default client-side navigation anchor routing.Legacy vs modern
Standard Full-Page Reload Links vs hx-boost SPA Navigation
Standard links cause white flashes and full reloads; `hx-boost` turns standard HTML into an instant SPA.
<nav><a href="/about">About</a></nav> // ❌ Triggers full page reload, re-executes all JS/CSS<body hx-boost="true"><a href="/about">About</a></body> // ✅ NEW: Instant SPA transitionsInterview gotchas
Context
Interviewers test your knowledge of inheritance and override rules in HTMX attributes.
The mechanical answer
Add **`hx-boost="false"`** directly onto the child element (or its local parent container). This tells HTMX to ignore the element and allow standard browser navigation (essential for external links, file downloads, or full-page logout redirects).
Trap
External links pointing to different domains (e.g. `href="https://google.com"`) are automatically ignored by `hx-boost`.
Context
Checks understanding of script execution lifecycle during boosted navigation.
The mechanical answer
By default, `hx-boost` only updates the `<body>` and `<title>`. Scripts and stylesheets in `<head>` are **not re-executed** on boosted navigations. If a destination page introduces a new `<script>` in its `<head>`, you can use the `head-support` extension (`hx-ext="head-support"`) to diff and merge `<head>` tags.
Trap
Inline scripts inside `<main>` will execute upon swap, but global scripts in `<head>` will not re-run.