Each recipe documents the short form, the expanded HTML, the optional
macro, and the server response contract. Recipes with an entry in the
Needs column require an installX() from
@hypermedia-components/core;
the rest (”—”) are pure htmx attributes.
Get any recipe’s scaffold with npx @hypermedia-components/cli add <name>;
machine-check your copy against its contract with
npx @hypermedia-components/cli validate.
Every recipe page also has a Live demo — real htmx requests
against a demo API served by this site’s Worker, implementing that
recipe’s server response contract under api/recipes/<name>/.
| Recipe | You need to… | Needs |
|---|
| Mutating form | post a form with inline 4xx errors, a success redirect, and a double-submit guard | installFieldErrors() |
| Field errors | distribute a server-sent validation-error fragment to the fields it names | installFieldErrors() |
| Multi-step form | build a wizard — the server owns the step and the draft; whole-step swaps | — |
| Confirm action | guard a destructive request behind a confirmation dialog | installConfirm() |
| Undo delete | delete immediately (optimistic delete) — the toast’s Undo restores the row within a grace period | installToast() |
| Request action | fire an htmx request from a button with a busy state | — |
| Inline edit | swap a value between display and edit modes in place (click-to-edit) | — |
| File upload | upload multipart files with a live progress bar and an out-of-band form reset | installUploadProgress() |
| Datagrid bulk actions | select rows with checkboxes and POST one action against all of them | installDatagridActions() |
| Transfer | assign / unassign across a dual listbox as a server round trip — whole-form swaps, zero custom JS | — |
| Cascading select | chain dependent selects for hierarchical selection; each change loads the next level | — |
| Copy to clipboard | copy a read-only value (URL, token, snippet) to the clipboard | installCopy() |
| Recipe | You need to… | Needs |
|---|
| Live search | search as you type (typeahead) — debounced input swaps the results | — |
| Filter popover | host a filter form in a popover that closes on success | installClosePopover() |
| Recipe | You need to… | Needs |
|---|
| Lazy panel | defer loading a panel until it is revealed | — |
| Lazy tree | load a tree branch’s children on first expand | installTree() |
| Data region | refresh a region on HX-Trigger invalidations (self-refreshing region) | — |
| Datagrid pagination | page a datagrid server-side with out-of-band row swaps | installDatagrid() |
| Recipe | You need to… | Needs |
|---|
| SSE updates | push fragment updates from the server over Server-Sent Events — named events and out-of-band pushes | — |
| SSE toast | turn SSE events with JSON payloads into allow-listed DOM events; toasts work unchanged | installSseDispatch() |
| Recipe | You need to… | Needs |
|---|
| Chat messages | append a chat exchange — user message + aria-busy assistant placeholder — from one composer POST, with a 422 path that never pollutes the transcript | installChatScroll() |
| Streaming response | fill the assistant placeholder over SSE — chunks append while aria-busy defers the announcement; done swaps in the final message and closes the stream | — |
| Recipe | You need to… | Needs |
|---|
| Chart | upgrade a server-sent data table into an Observable Plot SVG chart | installChart() + Plot |
| Recipe | You need to… | Needs |
|---|
| Remote dialog | load a dialog’s (modal’s) contents from the server on open | installRemoteDialog() + installCloseDialog() |
| Toast | fire toast notifications (snackbars) from the client or an HX-Trigger header | installToast() |