veilletech.fr
29 août Feed du jour
#06 WEB Article

htmx 4.0 : fetch, héritage explicite, et pas latest

Une version majeure qui refuse de s'installer toute seule : c'est aussi une position.

htmx 4.0 est publié après huit mois de travail : les internes passent de XMLHttpRequest à fetch, l'héritage d'attributs devient explicite via un suffixe :inherited, les noms d'événements sont normalisés et l'historique n'est plus caché dans localStorage. La version n'est volontairement pas marquée latest sur npm, pour ne pas mettre à jour les sites qui chargent htmx depuis un CDN non versionné.

2 min de lecturevidéo 1:21
Partager
Sommaire4 sections
  1. Ce qui se passe
  2. Les trois ruptures
  3. Ce qui arrive en plus
  4. À retenir

Ce qui se passe

htmx 4.0.0 est sorti, après huit mois de travail partis d'un portage de fixi et de la suite de tests htmx. Le changement interne principal : les requêtes passent par fetch(), là où htmx utilisait XMLHttpRequest depuis ses débuts pour des raisons de compatibilité.

Décision de distribution inhabituelle, et à connaître avant de planifier quoi que ce soit : la 4.0 n'est pas marquée latest sur npm. La ligne 2.x le reste jusqu'au début 2027, la 4.0 vit sous l'étiquette next. Motif affiché par l'équipe : ne pas mettre à jour de force les sites qui chargent htmx depuis une URL de CDN sans numéro de version. Le site de documentation, lui, référence désormais la 4.0.

Les trois ruptures

L'héritage d'attributs devient explicite. C'est le principal poste de migration. En htmx 2, beaucoup d'attributs se propageaient aux enfants, un héritage inspiré de CSS — puissant, et parfois difficile à suivre. En htmx 4, il faut le demander avec le suffixe :inherited :

HTML
<!-- htmx 2 -->
<div hx-confirm="Are you sure?">
    <button hx-delete="/item/1">Delete</button>
</div>

<!-- htmx 4 -->
<div hx-confirm:inherited="Are you sure?">
    <button hx-delete="/item/1">Delete</button>
</div>

Corollaire : hx-disinherit et compagnie n'ont plus d'objet et doivent être retirés. Un outil en ligne de commande — l'upgrade checker — repère les endroits à marquer.

Les événements sont normalisés au format htmx:phase:action[:sub-action] : htmx:beforeRequest devient htmx:before:request, htmx:afterSwap devient htmx:after:swap, htmx:configRequest devient htmx:config:request. La plupart des événements d'erreur fusionnent dans htmx:error, les réponses HTTP en erreur déclenchant htmx:response:error. Les événements htmx:xhr:* disparaissent — il n'y a plus de XMLHttpRequest — et les htmx:validation:* cèdent la place à la validation native du navigateur.

L'historique ne passe plus par localStorage. Le cache de pages y provoquait des restaurations incohérentes quand une bibliothèque tierce avait modifié le DOM. Au retour arrière, htmx refait la requête et échange le contenu dans <body>, ou dans l'élément [hx-history-elt] s'il existe. Pour retrouver un cache local, l'extension hx-history-cache s'appuie sur sessionStorage.

Ce qui arrive en plus

Deux nouveautés intégrées : les échanges par morphing, dérivés d'idiomorph et retravaillés pour htmx 4, et la balise <hx-partial>, plus lisible que les échanges hors bande dès qu'une réponse doit toucher plusieurs zones :

HTML
<hx-partial hx-target="#messages" hx-swap="beforeend">
    <div>New message</div>
</hx-partial>
<hx-partial hx-target="#count">
    <span>5</span>
</hx-partial>

Autour, les extensions profitent du passage à fetch() : hx-preload, hx-download, hx-alpine-compat, et trois extensions de streaming HTML — hx-sse (text/event-stream), hx-ws (WebSockets) et hx-multipart (multipart/mixed). L'équipe publie aussi hx-live, sa propre solution de scripting front, et un bundle htmax.js qui empaquette htmx avec les extensions les plus courantes.

Source : htmx, htmx 4.0.0 has been released! · guide de migration