htmx quirks

This is a “quirks” page, based on SQLite’s “Quirks, Caveats, and Gotchas In SQLite” page (https://www.sqlite.org/quirks.html). Attribute Inheritance

This is a “quirks” page, based on SQLite’s “Quirks, Caveats, and Gotchas In SQLite” page (https://www.sqlite.org/quirks.html).

Attribute Inheritance (https://htmx.org/quirks/#attribute-inheritance) Many attributes in htmx are inherited (https://htmx.org/docs/#inheritance): child elements can receive behavior from attributes located on parent elements.

As an example, here are two htmx-powered buttons that inherit their target (https://htmx.org/attributes/hx-target/) from a parent div:

This helps avoid repeating attributes, thus keeping code DRY (https://en.wikipedia.org/wiki/Don%27t_repeat_yourself).

On the other hand, as the attributes get further away elements, you lose Locality of Behavior (https://htmx.org/essays/locality-of-behaviour/) and it becomes more difficult to understand what an element is doing.

It is also possible to inadvertently change the behavior of elements by adding attributes to parents.

Some people prefer to disable inheritance in htmx entirely, using the htmx.config.disableInheritance configuration variable (https://htmx.org/docs/#config).

Here is a meta tag configuration that does so:

The Default Swap Strategy is innerHTML The hx-swap attribute allows you to control how a swap is performed. The default strategy is innerHTML, that is, to place the response HTML content within the target element.

Many people prefer to use the outerHTML strategy as the default instead.

You can change this behavior using the htmx.config.defaultSwapStyle configuration variable (https://htmx.org/docs/#config).

Here is a meta tag configuration that does so:

Targeting the body Always Performs an innerHTML Swap For historical reasons, if you target the body element, htmx will always perform an innerHTML swap.

This means you cannot change attributes on the body tag via an htmx request.

By Default 4xx & 5xx Responses Do Not Swap htmx has never swapped “error” status response codes (400s & 500s) by default.

This behavior annoys some people, and some server frameworks, in particular, will return a 422 - Unprocessable Entity response code to indicate that a form was not filled out properly.

This can be very confusing when it is first encountered.

You can configure the response behavior of htmx via the htmx:beforeSwap event or via the htmx.config.responseHandling config array.

Here is the default configuration:

{ “responseHandling”: [ {“code”:“204”, “swap”: false}, {“code”:“[23]..“, “swap”: true}, {“code”:“[45]..“, “swap”: false, “error”:true}, {“code”:“…“, “swap”: false}] }

Note that 204 No Content also is not swapped.

If you want to swap everything regardless of response code, you can use this configuration:

{ “responseHandling”: [ {“code”:“…“, “swap”: true}] }

If you want to specifically allow 422 responses to swap, you can use this configuration:

{ “responseHandling”: [ {“code”:“422”, “swap”: true}, {“code”:“204”, “swap”: false}, {“code”:“[23]..“, “swap”: true}, {“code”:“[45]..“, “swap”: false, “error”:true}, {“code”:“…“, “swap”: false}] }

Here is a meta tag allowing all responses to swap:

GET Requests on Non-Form Elements Do Not Include Form Values by Default If a non-form element makes a non-GET request (e.g. a PUT request) via htmx, the values of the enclosing form of that element (if any) will be included in the request (https://htmx.org/docs/#parameters).

However, if the element issues a GET, the values of an enclosing form will not be included. (https://github.com/bigskysoftware/htmx/blob/fb78106dc6ef20d3dfa7e54aca20408c4e4336fc/src/htmx.js#L3525)

If you wish to include the values of the enclosing form when issuing an GET you can use the hx-include attribute like so:

History Can Be Tricky (https://htmx.org/quirks/#history-can-be-tricky) htmx provides support for interacting with the browser’s history (https://htmx.org/docs/#history). This can be very powerful, but it can also be tricky, particularly if you are using 3rd party JavaScript libraries that modify the DOM.

There can also be security concerns (https://htmx.org/docs/#hx-history) when using htmx’s history support.

Most of these issues can be solved by disabling any local history cache and simply issuing a server request when a user navigates backwards in history, with the tradeoff that history navigation will be slower.

Here is a meta tag that disables history caching:

Some People Don’t Like hx-boost hx-boost is an odd feature compared with most other aspects of htmx: it “magically” turns all anchor tags and forms into AJAX requests.

This can speed the feel of these interactions up, and also allows the forms and anchors to continue working when JavaScript is disabled (https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement), however it comes with some tradeoffs:

• The history issues mentioned above can show up

• Only the body of the web page will be updated, so any styles and scripts in the new page head tag will be discarded

• The global javascript scope is not refreshed, so it is possible to have strange interactions between pages. For example a global let may start failing because a symbol is already defined.

Some members on the core htmx team feel that, due to these issues, as well as the fact that browsers have improved quite a bit in page navigation, it is best to avoid hx-boost and just use unboosted links and forms (https://unplannedobsolescence.com/blog/less-htmx-is-more/).

There is no doubt that hx-boost is an odd-man out when compared to other htmx attributes and suffers from the dictum that “If something magically works, then it can also magically break.”

Despite this fact, I (Carson) still feel it is useful in many situations, and it is used on the https://htmx.org (https://htmx.org) website.

Loading htmx asynchronously is unreliable (https://htmx.org/quirks/#loading-htmx-asynchronously-is-unreliable) htmx is designed to be loaded with a standard, blocking