|
1 | 1 | --- |
2 | 2 | title: "htmx Events Guide" |
3 | 3 | description: "Listen for htmx events to log, cancel, and modify request and swap behavior." |
| 4 | +keywords: ["events", "lifecycle", "event listener", "hx-on", "htmx.on", "request context", "ctx", "cancel request", "preventDefault", "CSRF", "add header", "modify request", "retarget", "reswap", "intercept", "hook", "scripting"] |
4 | 5 | --- |
5 | 6 |
|
6 | 7 | htmx triggers events at every step of the request and swap lifecycle. These events are the main extension point |
@@ -55,6 +56,50 @@ Inside an `hx-on:*` attribute every property of `detail` is already in scope, so |
55 | 56 |
|
56 | 57 | Element lifecycle events use `detail.elt` instead, which is the element htmx processed. |
57 | 58 |
|
| 59 | +## The ctx Object |
| 60 | + |
| 61 | +`ctx` is the request context object. It is created when a request is triggered and lives until the swap lifecycle |
| 62 | +ends. Properties marked **writable** can be changed in an event handler to alter htmx's behavior. |
| 63 | + |
| 64 | +| Property | Type | Writable | Description | |
| 65 | +|----------|------|----------|-------------| |
| 66 | +| `sourceElement` | `Element` | | The element that triggered the request | |
| 67 | +| `sourceEvent` | `Event` | | The DOM event that triggered the request | |
| 68 | +| `target` | `Element` | **yes** | The element that will receive the swapped content. Mutate in `htmx:after:request`. Note: `HX-Retarget` is applied after this event and will overwrite your value | |
| 69 | +| `swap` | `string` | **yes** | The swap style (e.g. `"innerHTML"`). Mutate in `htmx:after:request`. Note: `HX-Reswap` is applied after this event and will overwrite your value | |
| 70 | +| `select` | `string\|null` | **yes** | CSS selector from `hx-select`. Mutate in `htmx:after:request`. Note: `HX-Reselect` is applied after this event and will overwrite your value | |
| 71 | +| `selectOOB` | `string\|null` | **yes** | Selector string from `hx-select-oob`. Mutate in `htmx:after:request` | |
| 72 | +| `push` | `string\|null` | **yes** | URL to push into history. Mutate in `htmx:after:request`. Note: `HX-Push-Url` is applied after this event and will overwrite your value | |
| 73 | +| `replace` | `string\|null` | **yes** | URL to replace in history. Mutate in `htmx:after:request`. Note: `HX-Replace-Url` is applied after this event and will overwrite your value | |
| 74 | +| `confirm` | `string\|null` | | Confirmation message from `hx-confirm`. Read before any events fire — not writable from an event | |
| 75 | +| `transition` | `boolean` | **yes** | Whether to use the View Transitions API. Writable up to and including `htmx:before:swap` | |
| 76 | +| `request` | `object` | | Sub-object with request details — see below | |
| 77 | +| `response` | `object` | | Added after `fetch()`. Has `raw` (the `Response`), `status` (number), `headers` (`Headers`) | |
| 78 | +| `text` | `string` | **yes** | Added after the response body is read. The raw HTML string. Mutate in `htmx:after:request` — by `htmx:before:swap` the fragment is already parsed | |
| 79 | +| `title` | `string` | **yes** | Page title extracted from the response fragment. Set during `swap()` — writable up to `htmx:after:swap` | |
| 80 | +| `hx` | `object` | | Parsed `HX-*` response headers. Keys are lowercased with hyphens removed: `hx.trigger`, `hx.retarget`, `hx.reswap`, etc. | |
| 81 | + |
| 82 | +### ctx.request |
| 83 | + |
| 84 | +`ctx.request` maps directly onto the [Fetch API `RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit). |
| 85 | +Changes made in `htmx:config:request` are applied before the request is sent. |
| 86 | + |
| 87 | +| Property | Type | Description | |
| 88 | +|----------|------|-------------| |
| 89 | +| `action` | `string` | The request URL | |
| 90 | +| `method` | `string` | HTTP method (`"GET"`, `"POST"`, etc.) | |
| 91 | +| `headers` | `object` | Request headers. Add or change headers here | |
| 92 | +| `body` | `FormData\|URLSearchParams\|null` | Request body. A `FormData` at `htmx:config:request` (the right place to add values). Encoded to `URLSearchParams` or `null` for GET/DELETE before `fetch()` | |
| 93 | +| `validate` | `boolean` | Whether HTML5 form validation runs before the request | |
| 94 | +| `credentials` | `string` | Fetch credentials mode. Defaults to `"same-origin"` | |
| 95 | +| `signal` | `AbortSignal` | Abort signal. Fires when `htmx:abort` is triggered on the element | |
| 96 | +| `abort` | `function` | Call to abort the in-flight request | |
| 97 | +| `mode` | `string` | Fetch mode. Always reset to `htmx.config.mode` — cannot be overridden per-element | |
| 98 | +| `form` | `Element\|null` | The associated form element, if any | |
| 99 | +| `submitter` | `Element\|null` | The submit button that triggered the request, if any | |
| 100 | +| `anchor` | `string` | URL fragment (the part after `#`), if present in the action URL | |
| 101 | +| `timeout` | `number\|string` | Request timeout. Set via `hx-config="timeout:5s"` | |
| 102 | + |
58 | 103 | ## Cancelling An Event |
59 | 104 |
|
60 | 105 | htmx events are cancelable. Call `preventDefault()` to stop htmx from continuing: |
@@ -171,7 +216,7 @@ htmx.on('htmx:config:request', function (evt) { |
171 | 216 | Both are on the context, so you can change them up to the point of the swap: |
172 | 217 |
|
173 | 218 | ```javascript |
174 | | -htmx.on('htmx:before:swap', function (evt) { |
| 219 | +htmx.on('htmx:after:request', function (evt) { |
175 | 220 | if (evt.detail.ctx.response.status === 404) { |
176 | 221 | evt.detail.ctx.target = document.querySelector('#errors'); |
177 | 222 | } |
|
0 commit comments