Htmx provides an extension mechanism for defining and using extensions within htmx-based applications.

#Using Extensions

Using an extension involves two steps:

Here is an example

  <script src="/path/to/ext/debug.js" defer></script>
  <button hx-post="/example" hx-ext="debug">This Button Uses The Debug Extension</button>

This loads the debug extension off of the unpkg CDN and then adds the debug extension to the given button. (This will print out extensive logging for the button, for debugging purposes.)

Note that the hx-ext tag may be placed on parent elements if you want a plugin to apply to an entire part of the DOM, and on the body tag for it to apply to all htmx requests.

Tip: To use multiple extensions on one element, separate them with a comma:

  <button hx-post="/example" hx-ext="debug, json-enc">This Button Uses Two Extensions</button>

#Ignoring Extensions

By default, extensions are applied to the DOM node where it is invoked, along with all child elements inside of that parent node. If you need to disable an extension somewhere within the DOM tree, you can use the ignore: keyword to stop it from being used.

<div hx-ext="debug">
  <button hx-post="/example">This button used the debug extension</button>
  <button hx-post="/example" hx-ext="ignore:debug">This button does not</button>

#Included Extensions

htmx includes a set of extensions out of the box that address common developer needs. These extensions are tested against htmx in each distribution.

#Installing Extensions

You can find the source for the bundled extensions at https://unpkg.com/browse/htmx.org@1.9.12/dist/ext/. You will need to include the javascript file for the extension and then install it using the hx-ext attributes.

See the individual extension documentation for more details.

#Included Extensions List

ajax-headerincludes the commonly-used X-Requested-With header that identifies ajax requests in many backend frameworks
alpine-morphan extension for using the Alpine.js morph plugin as the swapping mechanism in htmx.
class-toolsan extension for manipulating timed addition and removal of classes on HTML elements
client-side-templatessupport for client side template processing of JSON/XML responses
debugan extension for debugging of a particular element using htmx
event-headerincludes a JSON serialized version of the triggering event, if any
head-supportsupport for merging the head tag from responses into the existing documents head
include-valsallows you to include additional values in a request
json-encuse JSON encoding in the body of requests, rather than the default x-www-form-urlencoded
idiomorphan extension for using the idiomorph morphing algorithm as a swapping mechanism
loading-statesallows you to disable inputs, add and remove CSS classes to any element while a request is in-flight.
method-overrideuse the X-HTTP-Method-Override header for non-GET and POST requests
morphdom-swapan extension for using the morphdom library as the swapping mechanism in htmx.
multi-swapallows to swap multiple elements with different swap methods
path-depsan extension for expressing path-based dependencies similar to intercoolerjs
preloadpreloads selected href and hx-get targets based on rules you control.
remove-meallows you to remove an element after a given amount of time
response-targetsallows to specify different target elements to be swapped when different HTTP response codes are received
restoredallows you to trigger events when the back button has been pressed
server-sent-eventsuni-directional server push messaging via EventSource
web-socketsbi-directional connection to WebSocket servers
path-paramsallows to use parameters for path variables instead of sending them in query or body

#Defining an Extension

To define an extension you call the htmx.defineExtension() function:

  htmx.defineExtension('my-ext', {
    onEvent : function(name, evt) {
        console.log("Fired event: " + name, evt);

Typically, this is done in a stand-alone javascript file, rather than in an inline script tag.

Extensions should have names that are dash separated and that are reasonably short and descriptive.

Extensions can override the following default extension points to add or change functionality:

    onEvent : function(name, evt) {return true;},
    transformResponse : function(text, xhr, elt) {return text;},
    isInlineSwap : function(swapStyle) {return false;},
    handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;},
    encodeParameters : function(xhr, parameters, elt) {return null;}