</> htmx
🚧 htmx 4.0 is under construction. Read changes →

Events

Htmx provides an extensive events system that can be used to modify and enhance behavior. Events are listed below.

Note: htmx 4.x uses a new event naming convention with the pattern htmx:[phase]:[action] (e.g., htmx:before:request, htmx:after:swap).

Control Events

Event - htmx:abort

This event is different than other events: htmx does not trigger it, but rather listens for it.

If you send an htmx:abort event to an element making a request, it will abort the request:

<button id="request-button" hx-post="/example">Issue Request</button>
<button onclick="htmx.trigger('#request-button', 'htmx:abort')">Cancel Request</button>

Event - htmx:confirm

This event is fired on every trigger for a request (not just on elements that have a hx-confirm attribute). It allows you to cancel (or delay) issuing the AJAX request. If you call preventDefault() on the event, it will not issue the given request. The detail object contains a function, evt.detail.issueRequest(skipConfirmation=false), that can be used to issue the actual AJAX request at a later point. Combining these two features allows you to create an asynchronous confirmation dialog.

document.body.addEventListener('htmx:confirm', function(evt) {
  if (!evt.detail.target.hasAttribute('hx-confirm')) return;

  evt.preventDefault();

  // Your custom confirmation logic here
  if (confirm("Are you sure?")) {
    evt.detail.issueRequest(true); // true to skip built-in confirm
  }
});
Details

Lifecycle Events

Event - htmx:before:init

Replaces: htmx:beforeProcessNode, htmx:beforeOnLoad

This event is triggered before htmx initializes a DOM node and processes its hx- attributes.

Details

Event - htmx:after:init

Replaces: htmx:afterProcessNode, htmx:afterOnLoad, htmx:load

This event is triggered after htmx has initialized a DOM node. Note that this event is also triggered when htmx is first initialized, with the document body as the target.

Details

Event - htmx:before:cleanup

Replaces: htmx:beforeCleanupElement

This event is triggered before htmx disables or removes an element from the DOM.

Details

Event - htmx:after:cleanup

This event is triggered after htmx has cleaned up an element.

Details

Event - htmx:before:process

This event is triggered before htmx processes an element and its descendants, setting up htmx behavior (triggers, boosting, hx-on attributes, etc.).

If you call preventDefault(), htmx will not process the element.

Details

Event - htmx:after:process

This event is triggered after htmx has finished processing an element and its descendants. This is useful for performing actions after htmx has set up all behaviors on new content.

document.body.addEventListener('htmx:after:process', function(evt) {
  // Initialize 3rd party libraries on newly processed content
  initializeWidgets(evt.detail.elt);
});
Details

Request Events

Event - htmx:config:request

Replaces: htmx:configRequest

This event is triggered before the request is made, allowing you to configure request parameters, headers, and other options.

document.body.addEventListener('htmx:config:request', function(evt) {
  let ctx = evt.detail.ctx;
  // Modify request configuration
  ctx.request.headers['X-Auth-Token'] = getToken();
});
Details

Event - htmx:before:request

Replaces: htmx:beforeRequest, htmx:beforeSend

This event is triggered before an AJAX request is issued. If you call preventDefault(), no request will occur.

Details

Event - htmx:after:request

Replaces: htmx:afterRequest

This event is triggered after an AJAX request has completed (whether successful or not).

Details

Event - htmx:finally:request

This event is always triggered after a request completes, similar to a finally block. Useful for cleanup operations.

Details

Swap Events

Event - htmx:before:swap

Replaces: htmx:beforeSwap

This event is triggered before any new content has been swapped into the DOM. If you call preventDefault(), no swap will occur.

You can modify swap behavior by setting properties on detail.ctx:

document.body.addEventListener('htmx:before:swap', function(evt) {
  let ctx = evt.detail.ctx;
  // Modify swap behavior
  ctx.swap = 'outerHTML';
  ctx.target = document.querySelector('#other-target');
});
Details

Event - htmx:after:swap

Replaces: htmx:afterSwap, htmx:afterSettle

This event is triggered after new content has been swapped into the DOM.

Details

Event - htmx:before:settle

This event is triggered before the settle phase begins, after content has been swapped into the DOM but before CSS transitions are applied.

Details

Event - htmx:after:settle

This event is triggered after the settle phase completes, including after any settle tasks (like CSS transitions) have finished.

Details

History Events

Event - htmx:before:history:update

Replaces: htmx:beforeHistoryUpdate, htmx:beforeHistorySave

This event is triggered before history is updated. You can modify the path or prevent the update.

Details

Event - htmx:after:history:update

This event is triggered after history has been updated.

Details

Event - htmx:after:push:into:history

Replaces: htmx:pushedIntoHistory

This event is triggered after a URL has been pushed into history.

Details

Event - htmx:after:replace:into:history

Replaces: htmx:replacedInHistory

This event is triggered after a URL has been replaced in history.

Details

Event - htmx:before:restore:history

Replaces: htmx:historyCacheMiss, htmx:historyRestore

This event is triggered before history restoration occurs (back/forward navigation).

Details

Error Event

Event - htmx:error

Replaces: htmx:responseError, htmx:sendError, htmx:sendAbort, htmx:swapError, htmx:targetError, htmx:timeout, htmx:onLoadError

This event consolidates all error events into a single event. It is triggered when an error occurs during any phase of the htmx request lifecycle.

document.body.addEventListener('htmx:error', function(evt) {
  let ctx = evt.detail.ctx;
  console.error('Error:', ctx.status, evt.detail.error);
});
Details

View Transition Events

Event - htmx:before:viewTransition

Replaces: htmx:beforeTransition

This event is triggered before a View Transition wrapped swap occurs. If you call preventDefault(), the View Transition will not occur and normal swapping will happen instead.

Details

Event - htmx:after:viewTransition

This event is triggered after a View Transition completes.

Details

Server-Sent Events (SSE)

Event - htmx:before:sse:stream

This event is triggered before an SSE (Server-Sent Events) stream is processed. You can call preventDefault() to cancel the stream processing.

Details

Event - htmx:after:sse:stream

This event is triggered after an SSE stream ends (either naturally or due to error/cancellation).

Details

Event - htmx:before:sse:message

This event is triggered before each SSE message is processed. You can set detail.message.cancelled = true to skip processing this message.

document.body.addEventListener('htmx:before:sse:message', function(evt) {
  // Skip messages of certain type
  if (evt.detail.message.event === 'heartbeat') {
    evt.detail.message.cancelled = true;
  }
});
Details

Event - htmx:after:sse:message

This event is triggered after an SSE message has been processed and swapped.

Details

Event - htmx:before:sse:reconnect

This event is triggered before reconnecting to an SSE stream (when using continuous mode). You can set detail.reconnect.cancelled = true to prevent the reconnection.

document.body.addEventListener('htmx:before:sse:reconnect', function(evt) {
  // Stop reconnecting after 10 attempts
  if (evt.detail.reconnect.attempt > 10) {
    evt.detail.reconnect.cancelled = true;
  }
});
Details