History, errors, and enhancement

Use request lifecycle events sparingly

Add cross-cutting behavior around beforeRequest, afterRequest, beforeSwap, afterSwap, and afterSettle without hiding core application logic.

8 minute lesson

~~~

HTMX exposes lifecycle events around two related processes: the HTTP request and the DOM update.

The request side includes:

  • htmx:beforeRequest, which can cancel with preventDefault()
  • htmx:beforeSend, immediately before transmission and too late to cancel
  • htmx:afterRequest, which reports the completed request as successful or failed

The response and DOM side includes:

  • htmx:beforeSwap, which can change shouldSwap, target, or swap behavior
  • htmx:afterSwap, after new DOM is inserted
  • htmx:afterSettle, after settling finishes

Do not use afterRequest as a substitute for a DOM event. With swap or settle delays, the request can be complete before the visual update you care about.

Use the narrowest event that matches the concern. Focus a newly revealed error after the swap; do not wait for afterRequest and then guess whether insertion finished.

A global listener is appropriate for shared observability:

document.addEventListener("htmx:afterRequest", event => {
  console.debug("HTMX request", {
    url: event.detail.xhr.responseURL,
    successful: event.detail.successful
  })
})

Avoid moving domain logic into global events. Authorization, validation, and state transitions belong on the server; method, URL, target, and swap should remain visible near the HTML. Otherwise the page becomes difficult to understand without tracing hidden listeners.

Lesson completed