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
detail.elt- the element in questiondetail.issueRequest(skipConfirmation=false)- function to issue the requestdetail.path- the path of the requestdetail.target- the element that triggered the requestdetail.triggeringEvent- the original event that triggered this requestdetail.verb- the verb of the request (e.g.GET)detail.question- the question fromhx-confirmattribute (if present)
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
detail.elt- the element being initialized
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
detail.elt- the newly initialized element
Event - htmx:before:cleanup
Replaces: htmx:beforeCleanupElement
This event is triggered before htmx disables or removes an element from the DOM.
Details
detail.elt- the element to be cleaned up
Event - htmx:after:cleanup
This event is triggered after htmx has cleaned up an element.
Details
detail.elt- the element that was cleaned up
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
detail.elt- the element about to be processed
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
detail.elt- the element that was processed
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
detail.ctx- the request context object containing:ctx.sourceElement- the element that triggered the requestctx.request- the request configuration with properties:action- the URLmethod- the HTTP methodheaders- headers objectbody- request body (FormData)credentials,mode,cache, etc. - fetch options
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
detail.ctx- the request context object
Event - htmx:after:request
Replaces: htmx:afterRequest
This event is triggered after an AJAX request has completed (whether successful or not).
Details
detail.ctx- the request context object
Event - htmx:finally:request
This event is always triggered after a request completes, similar to a finally block. Useful for cleanup operations.
Details
detail.ctx- the request context object
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
detail.ctx- the request context object
Event - htmx:after:swap
Replaces: htmx:afterSwap, htmx:afterSettle
This event is triggered after new content has been swapped into the DOM.
Details
detail.ctx- the request context object
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
detail.task- the swap task being settleddetail.newContent- array of newly swapped content elementsdetail.settleTasks- array of settle tasks (e.g., CSS transition callbacks)
Event - htmx:after:settle
This event is triggered after the settle phase completes, including after any settle tasks (like CSS transitions) have finished.
Details
detail.task- the swap task that was settleddetail.newContent- array of newly settled content elementsdetail.settleTasks- array of settle tasks that were executed
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
detail.ctx- the request context objectdetail.path- the path to be saved in history
Event - htmx:after:history:update
This event is triggered after history has been updated.
Details
detail.ctx- the request context object
Event - htmx:after:push:into:history
Replaces: htmx:pushedIntoHistory
This event is triggered after a URL has been pushed into history.
Details
detail.path- the path that was pushed
Event - htmx:after:replace:into:history
Replaces: htmx:replacedInHistory
This event is triggered after a URL has been replaced in history.
Details
detail.path- the path that was replaced
Event - htmx:before:restore:history
Replaces: htmx:historyCacheMiss, htmx:historyRestore
This event is triggered before history restoration occurs (back/forward navigation).
Details
detail.path- the path being restored
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
detail.ctx- the request context object containing:ctx.status- a string describing the errorctx.response- the response object (if available)
detail.error- the error that occurred (if available)
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
detail.ctx- the request context object
Event - htmx:after:viewTransition
This event is triggered after a View Transition completes.
Details
detail.ctx- the request context object
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
detail.ctx- the request context objectdetail.stream- the SSE stream configuration
Event - htmx:after:sse:stream
This event is triggered after an SSE stream ends (either naturally or due to error/cancellation).
Details
detail.ctx- the request context object
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
detail.ctx- the request context objectdetail.message- the SSE message object with properties:data- the message dataevent- the event type (if specified)id- the message ID (if specified)cancelled- set totrueto skip this message
Event - htmx:after:sse:message
This event is triggered after an SSE message has been processed and swapped.
Details
detail.ctx- the request context objectdetail.message- the SSE message object
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
detail.ctx- the request context objectdetail.reconnect- the reconnection configuration with properties:attempt- the reconnection attempt numberdelay- the delay before reconnection (in milliseconds)cancelled- set totrueto cancel the reconnection