HTMX Cheat Sheet
Complete reference of HTMX attributes, triggers, swap modifiers, response headers, and JavaScript API. Search by name or browse by category.
hx-get
Core RequestsIssues a GET request to the given URL when the element is triggered
Syntax
hx-get="[url]"Examples
GET request on button click
Auto-load on page readyGET on load
💡 Note: Default trigger is 'click' for most elements, 'change' for inputs, 'submit' for forms
hx-post
Core RequestsIssues a POST request to the given URL when triggered
Syntax
hx-post="[url]"Examples
POST form data on submit
POST with target
💡 Note: Submits form data (inputs within the form or hx-include'd elements)
hx-put
Core RequestsIssues a PUT request to the given URL when triggered
Syntax
hx-put="[url]"Examples
PUT with included form data
💡 Note: Use for full resource updates (REST convention)
hx-patch
Core RequestsIssues a PATCH request to the given URL when triggered
Syntax
hx-patch="[url]"Examples
PATCH on input change
💡 Note: Use for partial resource updates (REST convention)
hx-delete
Core RequestsIssues a DELETE request to the given URL when triggered
Syntax
hx-delete="[url]"Examples
Delete and remove element
DELETE with confirmation
💡 Note: Combine with hx-confirm to prevent accidental deletions
hx-target
Targets & SwapsSpecifies the target element to swap the response content into
Syntax
hx-target="[css-selector | this | closest | find | next | previous]"Examples
Target by ID
Target self
Closest ancestor
Find descendant
Next element
💡 Note: Defaults to the element itself. Use CSS selectors or relative specifiers: this, closest, find, next, previous
hx-swap
Targets & SwapsControls how the response is swapped into the DOM (default: innerHTML)
Syntax
hx-swap="[innerHTML | outerHTML | beforebegin | afterbegin | beforeend | afterend | delete | none] [modifier]"Examples
Default inner swapReplace inner content (default)
Replace element itselfReplace entire element
Append items to list
Append to end
Prepend to startPrepend to start
Smooth swapWith swap delay
Use view transitionsWith View Transitions API
💡 Note: Modifiers: swap:<time>, settle:<time>, scroll:[top|bottom], show:[selector|top|bottom], focus-scroll:true, transition:true, ignoreTitle:true
hx-swap-oob
Targets & SwapsMarks content in the response to be swapped out-of-band (into a different element)
Syntax
hx-swap-oob="true | [swap-style] | [swap-style]:[css-selector]"Examples
Alert!OOB swap by ID match
New alert contentOOB with explicit target
💡 Note: Used in server responses to update multiple parts of the page simultaneously without JavaScript
hx-trigger
TriggersSpecifies the event that triggers the request (default: click for buttons, change for inputs, submit for forms)
Syntax
hx-trigger="[event] [modifier] [, event modifier ...]"Examples
Search with debounce
Auto-loadTrigger on page load
Poll every 5sPolling
Load only onceFire only once
Throttle clicksThrottle requests
Lazy load on scrollTrigger on viewport intersect
On scroll revealTrigger when scrolled into view
Trigger from another element
💡 Note: Modifiers: once, changed, delay:<time>, throttle:<time>, from:<selector>, target:<selector>, consume, queue:[first|last|all|none]
hx-on
TriggersHandles any event with inline scripts (replaces x-on / v-on patterns without Alpine/Vue)
Syntax
hx-on:[event]="[javascript]" or hx-on::event="[javascript]"Examples
Disable button before request
ContentRun JS after swap
Handle DOM events
💡 Note: hx-on:htmx:* handles HTMX lifecycle events. hx-on:[dom-event] handles standard DOM events. Use :: shorthand for htmx events.
hx-boost
Boosting & URLProgressively enhances anchor tags and forms to use HTMX (AJAX-style navigation)
Syntax
hx-boost="true | false"Examples
All links and forms use HTMXEnable globally
Opt-out individual link
💡 Note: Converts <a> to GET requests and <form> to POST, swapping body innerHTML. Enables browser history automatically.
hx-push-url
Boosting & URLPushes the URL of the AJAX request to the browser's address bar (browser history entry)
Syntax
hx-push-url="true | false | [url]"Examples
Push request URL to history
Push custom URL
💡 Note: Creates a browser history entry, enabling back/forward navigation
hx-replace-url
Boosting & URLReplaces the current URL in the browser's address bar without creating a history entry
Syntax
hx-replace-url="true | false | [url]"Examples
Replace URL without history entry
💡 Note: Similar to hx-push-url but uses replaceState instead of pushState
hx-include
Forms & DataIncludes additional element values in the request
Syntax
hx-include="[css-selector]"Examples
Include form from elsewhere
Include by name attribute
Include closest form
💡 Note: Use CSS selectors. The element and all its inputs are included in the request
hx-params
Forms & DataFilters which parameters are submitted with a request
Syntax
hx-params="* | none | not [list] | [list]"Examples
Exclude specific field
Whitelist fields
Send no params
💡 Note: * = all params (default), none = no params, not [list] = exclude listed params
hx-vals
Forms & DataAdds additional values to the request parameters (as JSON or js:expression)
Syntax
hx-vals='{"key": "value"}' or hx-vals="js:{key: expression}"Examples
Add static JSON values
Dynamic JS values
💡 Note: JSON values are merged into the request parameters. Use js: prefix for dynamic values.
hx-encoding
Forms & DataChanges the request encoding type
Syntax
hx-encoding="multipart/form-data"Examples
File upload form
💡 Note: Use multipart/form-data for file uploads. Default is application/x-www-form-urlencoded.
hx-indicator
IndicatorsSpecifies the element to show during a request (using the htmx-request CSS class)
Syntax
hx-indicator="[css-selector]"Examples
Show spinner during request
Target ancestor
💡 Note: The .htmx-indicator class is opacity:0 by default; during requests it becomes opacity:1
hx-disabled-elt
IndicatorsDisables the specified element during a request
Syntax
hx-disabled-elt="[css-selector | this | closest | find]"Examples
Disable button while submitting
Disable all inputs in form
💡 Note: Adds the disabled attribute during the request, removes it when complete
hx-history
HistoryControls browser history caching for the element's content
Syntax
hx-history="false"Examples
Sensitive content (not cached in history)Disable history snapshot for sensitive data
💡 Note: Use false to prevent sensitive content from being stored in the browser's history cache
hx-history-elt
HistoryMarks an element as the history snapshot target (what gets saved in browser history)
Syntax
hx-history-eltExamples
Main content areaUse this element for history snapshots
💡 Note: Only one element per page. Defaults to <body> if not specified.
hx-sync
SyncControls how requests from multiple elements are synchronized
Syntax
hx-sync="[selector]:[strategy]"Examples
Fast typingCancel previous, replace with new
Abort if form is already submitting
Queue last requestQueue only the last request
💡 Note: Strategies: drop (ignore), abort, replace, queue [first|last|all]. Default selector: this
hx-confirm
ConfirmShows a confirm() dialog before issuing a request
Syntax
hx-confirm="[message]"Examples
Confirm before delete
Confirm before form submit
💡 Note: Uses the browser's native confirm() dialog. For custom dialogs, use htmx:confirm event.
hx-select
ConfirmSelects a subset of the server response to swap in
Syntax
hx-select="[css-selector]"Examples
Extract partial response
💡 Note: Useful when the server returns a full page but you only need part of it
hx-select-oob
ConfirmSelects content from a response to swap in out-of-band (into elements matching by ID)
Syntax
hx-select-oob="[css-selector], [css-selector]:[swap-style]"Examples
Select main and OOB update sidebar
💡 Note: Combines hx-select with OOB swapping in a single request
hx-ext
ExtensionsEnables HTMX extensions for enhanced functionality
Syntax
hx-ext="[extension-name], [extension-name]"Examples
Use JSON encoding globallyJSON encoding extension
Preload links on hoverPreload extension
WebSocket chatWebSocket extension
Server-Sent EventsSSE extension
💡 Note: Popular extensions: json-enc, ws (WebSockets), sse (Server-Sent Events), preload, head-support, class-tools, morphdom-swap
HX-Trigger
Response HeadersServer response header: triggers client-side events after swap
Syntax
HX-Trigger: eventName
HX-Trigger: {"event1": "val1", "event2": "val2"}Examples
HX-Trigger: showModalTrigger simple event
HX-Trigger: {"showMessage": "Item saved!"}Trigger event with data
HX-Trigger-After-Swap: refreshCartTrigger after swap completes
HX-Trigger-After-Settle: updateCountTrigger after settle completes
💡 Note: Variants: HX-Trigger (immediately), HX-Trigger-After-Swap, HX-Trigger-After-Settle
HX-Redirect
Response HeadersServer response header: redirects the client to a new URL (full page reload)
Syntax
HX-Redirect: [url]Examples
HX-Redirect: /dashboardRedirect to dashboard after action
💡 Note: Causes a full page navigation, not an HTMX swap. Use HX-Push-Url for soft navigation.
HX-Refresh
Response HeadersServer response header: triggers a full page refresh
Syntax
HX-Refresh: trueExamples
HX-Refresh: trueForce full page reload
💡 Note: Causes the browser to do a full reload of the current page
HX-Retarget
Response HeadersServer response header: changes the target element for the response swap
Syntax
HX-Retarget: [css-selector]Examples
HX-Retarget: #error-areaRedirect response to error container on failure
💡 Note: Overrides the hx-target attribute from the client. Useful for error handling.
HX-Reswap
Response HeadersServer response header: changes the swap method for the response
Syntax
HX-Reswap: [swap-style]Examples
HX-Reswap: outerHTMLOverride client's swap style
HX-Reswap: nonePrevent swap (but still trigger events)
💡 Note: Overrides the hx-swap attribute from the client
HX-Push-Url
Response HeadersServer response header: pushes a URL to the browser history stack
Syntax
HX-Push-Url: [url]Examples
HX-Push-Url: /items/123Push canonical URL to history
HX-Push-Url: falsePrevent URL push even if hx-push-url is set
💡 Note: Overrides hx-push-url from the client. Use false to suppress client-side push.
HX-Location
Response HeadersServer response header: pushes a URL to the history stack without page reload (AJAX navigation)
Syntax
HX-Location: [url] or HX-Location: {"path": "/url", "target": "#content"}Examples
HX-Location: /new-pageSoft navigate to new page
{"path": "/new-page", "target": "#main", "swap": "innerHTML"}Full control over location swap
💡 Note: More powerful than HX-Redirect — does a client-side swap with history update, no full reload
htmx-request
CSS ClassesCSS class added to the element making a request (and its indicator) while a request is in flight
Syntax
.htmx-request { /* styles during request */ }Examples
.htmx-request { opacity: 0.5; }
.htmx-request .spinner { display: inline; }Dim element during request
.htmx-indicator {
opacity: 0;
transition: opacity 200ms ease-in;
}
.htmx-request .htmx-indicator {
opacity: 1;
}Fade in spinner
💡 Note: Applied to both the requesting element and any hx-indicator targets
htmx-swapping
CSS ClassesCSS class applied to target element during the swap phase
Syntax
.htmx-swapping { /* styles during swap */ }Examples
.htmx-swapping {
opacity: 0;
transition: opacity 100ms ease-out;
}Fade out before new content appears
💡 Note: Use with swap:Xms modifier on hx-swap to control the duration
htmx-settling
CSS ClassesCSS class applied to target element during the settle phase (after new content is inserted)
Syntax
.htmx-settling { /* styles during settle */ }Examples
.htmx-added {
opacity: 0;
}
.htmx-settling .htmx-added {
opacity: 1;
transition: opacity 300ms ease-in;
}Fade in new content
💡 Note: The settle phase allows CSS transitions to run after new content is inserted
htmx-added
CSS ClassesCSS class briefly added to new content after it is swapped in, enabling entry animations
Syntax
.htmx-added { /* entry animation start state */ }Examples
.htmx-added {
opacity: 0;
transform: translateY(-10px);
}
.htmx-added {
transition: opacity 300ms, transform 300ms;
}Slide-in animation for new items
💡 Note: Added immediately after swap, removed after settle. Perfect for list item animations.
htmx.ajax()
JavaScript APIIssues an HTMX-style AJAX request programmatically from JavaScript
Syntax
htmx.ajax(verb, path, context)Examples
htmx.ajax('GET', '/api/data', '#target')GET and swap into #target
htmx.ajax('POST', '/api/create', {
target: '#result',
swap: 'beforeend',
values: { name: 'test' }
})POST with target and values
htmx.ajax('DELETE', '/api/item/1', {
target: 'closest li',
swap: 'delete'
})DELETE with closest selector
💡 Note: Returns a Promise. Context can be a CSS selector string or an object with target, swap, values, source, etc.
htmx.trigger()
JavaScript APITriggers an event on an element
Syntax
htmx.trigger(element, eventName, detail)Examples
htmx.trigger('#my-form', 'submit')Trigger form submission
htmx.trigger(document.body, 'refreshData', { id: 42 })Trigger custom event with data
💡 Note: Useful for triggering hx-trigger events programmatically
htmx.process()
JavaScript APIProcesses an element and its children, initializing HTMX attributes on dynamically added content
Syntax
htmx.process(element)Examples
const div = document.createElement('div');
div.innerHTML = '';
document.body.appendChild(div);
htmx.process(div);Initialize HTMX on dynamically injected HTML
💡 Note: Required when you add HTMX-attributed HTML to the DOM outside of HTMX itself (e.g., via vanilla JS)
htmx.on()
JavaScript APIAttaches an event listener to an element for HTMX or DOM events
Syntax
htmx.on(target, eventName, callback) or htmx.on(eventName, callback)Examples
htmx.on('htmx:afterSwap', function(evt) {
console.log('Swapped:', evt.detail);
});Listen to HTMX lifecycle event
htmx.on('#form', 'htmx:beforeRequest', function(evt) {
evt.preventDefault(); // cancel
});Cancel a request
💡 Note: Returns the event listener function for later removal. Works like addEventListener but with HTMX event name normalization.
hx-swap Values Reference
All 8 swap strategies for controlling how the server response enters the DOM.
| Value | Description |
|---|---|
| innerHTML | Replace inner HTML of target (default) |
| outerHTML | Replace entire target element |
| beforebegin | Insert before the target element |
| afterbegin | Insert as first child of target |
| beforeend | Insert as last child of target |
| afterend | Insert after the target element |
| delete | Delete target regardless of response |
| none | No swap — response is discarded (events still fire) |
Modifiers can be appended to any swap value: swap:<time>, settle:<time>, scroll:[top|bottom], show:selector, transition:true, focus-scroll:true
hx-trigger Modifiers Reference
Modifiers can be chained after the event name in hx-trigger.
| Modifier | Description |
|---|---|
| once | Trigger only once, then stop listening |
| changed | Only trigger if the element's value has changed |
| delay:<time> | Wait before triggering (debounce). E.g. delay:500ms |
| throttle:<time> | Throttle: minimum time between triggers. E.g. throttle:2s |
| from:<selector> | Listen for event on a different element. E.g. from:window |
| target:<selector> | Only trigger if event target matches selector |
| consume | Consume the event, preventing it from bubbling |
| queue:[first|last|all|none] | Queue strategy for multiple requests |
| intersect | Fires when element enters viewport (Intersection Observer) |
| revealed | Fires when element is scrolled into view |
| load | Fires once when element is loaded |
| every <time> | Polling: trigger at an interval. E.g. every 5s |
What is HTMX?
🌐 Hypermedia-Driven Development
HTMX is a lightweight JavaScript library (~14kb min.gz) that extends HTML with custom attributes to make any element capable of issuing HTTP requests. Instead of writing JavaScript to fetch data and update the DOM, you describe the behavior directly in HTML.
The core idea is hypermedia — the server sends HTML fragments, not JSON, and the browser swaps them into the page. This is how the web was originally designed, but now turbocharged for modern interactivity.
<!-- This button makes a real HTTP GET, swaps the response into #content -->
<button hx-get="/api/data" hx-target="#content">Load</button>
🚀 HTMX vs React/Vue SPAs
HTMX approach
- ✅ Server renders HTML (any language/framework)
- ✅ No JSON serialization/deserialization layer
- ✅ No client-side state management
- ✅ Works with any backend (PHP, Rails, Django, Laravel...)
- ✅ Progressive enhancement — works without JS
- ✅ ~14kb bundle, zero build step required
- ⚠️ Less suited for highly interactive client UIs
React/Vue SPA approach
- ✅ Rich client-side interactivity
- ✅ Instant UI updates without server round-trips
- ✅ Component reusability and large ecosystem
- ⚠️ JSON API layer required
- ⚠️ Client-side state management complexity
- ⚠️ Larger bundles, build pipeline required
- ⚠️ SEO requires SSR setup
Rule of thumb: Use HTMX for content-heavy apps where most interactivity is CRUD operations. Use React/Vue when you need a desktop-app-like client experience with complex local state.
⚖️ HTMX vs Alpine.js vs Stimulus
| Feature | HTMX | Alpine.js | Stimulus |
|---|---|---|---|
| Primary role | Server-driven partial page updates | Client-side reactivity & state | Connecting JS to existing HTML |
| State lives in | Server | Browser (x-data) | JS controllers |
| Server response | HTML fragments | Typically JSON | Either (JSON or HTML) |
| Bundle size | ~14kb | ~16kb | ~80kb |
| Best for | CRUD-heavy apps, forms, tables | Dropdowns, tabs, local UI state | Hotwire/Turbo, Rails apps |
| Works together? | Yes — pairs great with Alpine.js | Yes — use with HTMX for UI state | Yes — separate concerns cleanly |
| No-JS fallback | ✅ (forms still submit) | ❌ | Partial |
Common stack: HTMX for server requests + Alpine.js for local client UI state = covers 90% of web app needs without React.
⚡ Getting Started with HTMX
1. Add the Script Tag
<script src="https://unpkg.com/htmx.org@2.0.4"></script>2. Your First HTMX Button
<button hx-get="/api/hello" hx-target="#result">Say Hello</button>
<div id="result"></div>3. Server Returns HTML (not JSON)
# Flask / Django / Laravel / Rails — just return HTML
return "<p>Hello from the server!</p>"HTMX Philosophy: "The simplest tools that do the job." HTMX reclaims the power of hypermedia — the original architecture of the web — while keeping your HTML the source of truth. No state management, no virtual DOM, no build step. Just HTML and a server that knows how to render it. 🌐
HTMX Pro Tips
Common Patterns
- Use
hx-boost="true"on<body>for free SPA-like navigation - Combine
hx-trigger="keyup changed delay:300ms"for search inputs - Use
hx-swap-oob="true"to update counters/notifications in a single response - Add
hx-disabled-elt="this"to buttons to prevent double-submission - Use
hx-indicatorwith CSS transitions for smooth loading states
HTMX Best Practices
- Return only the HTML fragment you need (not a full page)
- Use
HX-Triggerresponse header to coordinate cross-page updates - Keep IDs stable — HTMX targets elements by CSS selector
- Pair with Alpine.js for purely client-side UI state (modals, tabs)
- Test with JS disabled first — good HTMX apps degrade gracefully
- Use
hx-confirmfor destructive actions