The hx-boost attribute makes links and forms use AJAX.
Without JavaScript, they retain their normal browser behavior through progressive enhancement.
Syntax
| Element | Request | Trigger | History | Target | Swap |
|---|---|---|---|---|---|
<a> | GET to href | click | Push URL | <body> | outerSync |
<form> | GET or POST to action | submit | No push | <body> | outerSync |
Override target, swap, and history behavior with their corresponding attributes. Boosted links always use click.
Boost several links from a parent:
<div hx-boost:inherited="true"> <a href="/page1">Page 1</a> <a href="/page2">Page 2</a> </div>
Each link sends GET, pushes its URL, and swaps the response into <body> with outerSync.
outerSync replaces body children and syncs body attributes without replacing the <body> element.
Boost a form directly:
<form hx-boost="true" action="/example" method="post"> <input name="email" type="email"> <button>Submit</button> </form>
The form sends POST and swaps the response into <body> without pushing a URL. Add hx-push-url to create a history entry.
Advanced Syntax
You can configure boost behavior using a config string that sets swap, target, and other options directly
on the hx-boost attribute. Use hx-boost:inherited to pass that config down to all boosted descendants.
<!-- outerSync + select + target: pull #main from the full-page response and swap it in place, syncing #main's attributes (class, data-*, etc.) at the same time --> <body hx-boost:inherited="swap:outerSync select:#main target:#main"> <nav> <!-- These links inherit the boost config above --> <a href="/page1">Go To Page 1</a> <a href="/page2">Go To Page 2</a> <!-- Nested override: descendants of this div use a different boost config --> <div hx-boost:inherited="swap:'innerHTML strip' target:#sidebar"> <a href="/sidebar">Sidebar</a> <!-- Per-element override: this link uses its own config, ignoring all inherited --> <a href="/modal" hx-boost="swap:beforeend target:#modals">Open Modal</a> <!-- Disable boost for this link --> <a href="/external" hx-boost="false">External</a> </div> </nav> <!-- Non-boosted htmx elements are unaffected by hx-boost:inherited --> <div hx-get="/data" hx-trigger="load">Loading...</div> <div id="main"></div> <div id="sidebar"></div> <div id="modals"></div> </body>
The key advantage is that boost config only applies to boosted elements (links and forms), unlike inherited
hx-* attributes which would affect all descendant htmx elements.
Priority Order
Boost config overrides explicit hx-* attributes on the element:
- Boost config (highest priority)
- Explicit
hx-*attributes - Default values (lowest priority)
This allows you to:
- Set base defaults with
hx-target,hx-swapon elements - Override them with
hx-boost:inheritedat any level - Use
hx-boost="true"orhx-boost="false"to enable/disable
Supported modifiers:
swap:STYLE- Swap strategy (outerSync,innerHTML,outerHTML, etc.)target:SELECTOR- Target element selectorselect:SELECTOR- Content selection from response (works withouterSync; useinnerHTML stripinstead ofinnerHTML+selectwhen targeting a non-body element)
Anchor Boosting
Anchors are boosted when they navigate to the same origin in the current window:
<a href="/example">Same-origin link</a> <a href="/example" target="_self">Same-origin link targeting this window</a>
These anchors are not boosted:
<a href="https://other-domain.com/example">Different origin</a> <a href="#section">Local anchor</a> <a href="/report.pdf" download>Browser download</a> <a href="/example" target="_blank">New window or tab</a>
Notes
- All requests are done via AJAX, so keep that in mind when doing things like redirects
- To find out if the request results from a boosted anchor or form, look for
HX-Boostedin the request header - Selectively disable boost on child elements with
hx-boost="false" - Disable the replacement of elements via boost, and their children, with
hx-preserve="true"