htmx Cheat Sheet
Quick reference for htmx — core attributes, request types, targets, swapping, triggers, events, and common patterns. All essential htmx patterns in one page.
Core Attributes
| hx-get="/api/data" | Issue GET request to URL |
| hx-post="/api/submit" | Issue POST request |
| hx-put="/api/update/1" | Issue PUT request |
| hx-patch="/api/patch/1" | Issue PATCH request |
| hx-delete="/api/delete/1" | Issue DELETE request |
| hx-target="#result" | Place response into #result element |
| hx-swap="innerHTML" | How to swap content (default: innerHTML) |
| hx-trigger="click" | Event that triggers request (default: natural event) |
| hx-select="#fragment" | Select fragment from response HTML |
| hx-indicator="#spinner" | Show element during request |
Swap Strategies
| hx-swap="innerHTML" | Replace inner HTML of target (default) |
| hx-swap="outerHTML" | Replace entire target element |
| hx-swap="beforebegin" | Insert before target element |
| hx-swap="afterbegin" | Insert at start of target |
| hx-swap="beforeend" | Append to end of target |
| hx-swap="afterend" | Insert after target element |
| hx-swap="delete" | Delete target element |
| hx-swap="none" | No swap — just trigger request |
| hx-swap="innerHTML swap:500ms" | Swap with 500ms delay |
| hx-swap="innerHTML settle:300ms" | Settle (attribute change) delay |
Triggers
| hx-trigger="click" | Trigger on click (default for buttons) |
| hx-trigger="change" | Trigger on input change |
| hx-trigger="submit" | Trigger on form submit |
| hx-trigger="keyup changed delay:500ms" | Debounced keyup (search pattern) |
| hx-trigger="load" | Trigger on element load |
| hx-trigger="revealed" | Trigger when element scrolled into view |
| hx-trigger="intersect" | Trigger on intersection observer |
| hx-trigger="every 2s" | Poll every 2 seconds |
| hx-trigger="click once" | Only trigger once |
| hx-trigger="click from:body" | Listen for clicks on body |
Request Control
| hx-vals='{"key": "value"}' | Add extra values to request |
| hx-params="*" | Include all params (default) |
| hx-params="none" | Include no params |
| hx-params="not fieldName" | Exclude specific param |
| hx-headers='{"X-Custom": "value"}' | Add custom request headers |
| hx-include="#other-form" | Include inputs from another element |
| hx-confirm="Are you sure?" | Show confirm dialog before request |
| hx-disable-elt="this" | Disable element during request |
| hx-encoding="multipart/form-data" | Set encoding for file uploads |
Response Headers (Server)
| HX-Redirect: /new-page | Client-side redirect |
| HX-Refresh: true | Full page refresh |
| HX-Retarget: #other | Change swap target |
| HX-Reswap: outerHTML | Change swap strategy |
| HX-Trigger: showMessage | Trigger client-side event |
| HX-Push-Url: /new-url | Push URL to history |
| HX-Replace-Url: /new-url | Replace URL in history |
| HX-Reselect: #fragment | Change response selection |
Common Patterns
| hx-get="/search" hx-trigger="keyup changed delay:300ms" hx-target="#results" | Live search with debounce |
| hx-delete="/item/1" hx-target="closest tr" hx-swap="outerHTML swap:500ms" | Delete row with animation |
| hx-get="/page?p=2" hx-trigger="revealed" hx-swap="afterend" | Infinite scroll |
| hx-post="/toggle" hx-swap="outerHTML" | Toggle component (replace self) |
| hx-get="/modal" hx-target="#modal-container" hx-trigger="click" | Load modal content on demand |
| hx-post="/form" hx-swap="none" hx-on::after-request="this.reset()" | Submit form and reset |
| hx-get="/tab/1" hx-target="#tab-content" hx-push-url="true" | Tab navigation with URL update |
Step-by-Step Guide
Read Guide →