HTMX on a Static Site
Every example on this page actually works — no backend, no API, no fake endpoints. Just HTMX loading pre-built HTML fragments from the /fragments/ directory.
1. Click to Load Content
The simplest HTMX pattern: click a link, load a static HTML file, swap it in.
How it works: The button has hx-get="/fragments/greeting.html" — HTMX fetches that static file and swaps its HTML into #load-result. That's it.
2. Tabbed Content
Each tab loads a different static HTML fragment. No JavaScript tab library needed.
Click a tab to load content...
How it works: Each tab button has a different hx-get pointing to a static fragment file. They all target the same #tab-content container.
3. Click-to-Reveal Details
Expand sections on demand without loading everything upfront.
How it works: Each heading is a button with hx-get that loads a fragment into the panel below it. Content is only fetched when the user clicks.
4. Boosted Navigation
Add hx-boost="true" to links and HTMX converts them to AJAX requests that swap the body — instant, SPA-like navigation with zero JavaScript.
How it works: The hx-boost="true" on the <nav> container applies to all links inside it. Clicking any link fetches the page via AJAX and swaps the body — no full page reload, back button still works.
5. Lazy Loading (Scroll to Reveal)
This content loads automatically when you scroll it into view:
How it works: hx-trigger="revealed" fires the GET request when the element enters the viewport. Perfect for below-the-fold content.
6. Load More Pattern
Click to append additional content below existing content.
📄 Initial Content
This was rendered at build time. Click below to load more.
How it works: hx-swap="beforeend" appends the loaded fragment after existing children instead of replacing them.
7. Inline Element Swap
Replace a single element inline within text.
The current status is: unknown —
How it works: hx-swap="outerHTML" replaces the entire target element (not just its children), useful for swapping badges, status indicators, or inline widgets.
How This Works — No Backend Required
The key insight: HTMX doesn't care if the response comes from a server or a static file. It just makes an HTTP GET, gets HTML back, and swaps it in.
static/
fragments/
greeting.html <- loaded by "Click to Load"
tab-overview.html <- loaded by "Overview" tab
tab-attributes.html <- loaded by "Attributes" tab
tab-examples.html <- loaded by "Examples" tab
detail-htmx.html <- loaded by accordion
detail-static.html <- loaded by accordion
lazy-content.html <- loaded on scroll
more-content.html <- loaded by "Load More"
At build time, generate your fragment files. At runtime, HTMX loads them on demand. That's the entire architecture.
The Pattern
<!-- Any element can trigger a load -->
<button hx-get="/fragments/content.html"
hx-target="#result"
hx-swap="innerHTML">
Load Content
</button>
<!-- Target container for swapped content -->
<div id="result"></div>
Useful hx-swap Values
| Value | Behavior |
|---|---|
innerHTML |
Replace children of target |
outerHTML |
Replace the entire target element |
beforeend |
Append after last child (load more) |
afterbegin |
Insert before first child |
beforebegin |
Insert before the target |
afterend |
Insert after the target |
Useful hx-trigger Values
| Value | Behavior |
|---|---|
click |
On click (default for buttons) |
revealed |
When element scrolls into view |
load |
Immediately when element loads |
every 5s |
Polling interval (needs a server) |