Triggers, forms, and feedback

Choose a custom trigger

Request on load, visibility, input, a custom event, or a timed interval when the feature genuinely requires it.

Natural triggers cover clicks, changes, and submits. Some features need a request without any direct user action on the element: content that loads when scrolled into view, a status that refreshes on a timer, or a request started by another part of your code. hx-trigger handles all of these.

<section hx-get="/recommendations" hx-trigger="revealed">
  Loading recommendations…
</section>

Use load when a fragment is required immediately after initialization. Use revealed when scrolling the window should lazy-load it. For an element inside an overflow container, use intersect so Intersection Observer detects visibility correctly. The placeholder text matters here: it is what people see until the trigger fires, so make it honest about what is coming.

Polling uses a timing declaration:

<div hx-get="/jobs/42/status" hx-trigger="every 5s">
  Processing…
</div>

The server can return status 286 to stop HTMX polling when the job reaches a terminal state. Without that stop condition, finished jobs keep generating a request every five seconds for as long as the tab stays open. Still avoid polling when a user action, normal refresh, SSE extension, or WebSocket extension better matches the update model.

The most flexible option is a custom event, which keeps the HTTP behavior visible in markup:

<div hx-get="/notifications"
  hx-trigger="notificationsChanged from:body"></div>

Another script or an HX-Trigger response header can emit notificationsChanged. Dispatching it from JavaScript is one line:

document.body.dispatchEvent(new Event('notificationsChanged'))

The from:body modifier tells HTMX to listen on the body instead of the element itself. This solves cases where no element event fits. A <select> where one specific option must load content is a classic example: options fire no events of their own, so a change handler dispatches a custom event on the body and the HTMX element reacts to it. The event connects features; the element still declares the route and response target.

When a custom trigger seems dead, check the wiring first: the event must be dispatched on the same element named in from:. Test it by dispatching the event from the DevTools console and watching the Network panel for the request.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →