htmx 4.0.0 is uitgebracht!
Het htmx-team is zeer blij met de release van htmx 4.0.0! Dit is het resultaat van acht maanden werk (plus een game) en we zijn erg tevreden met het resultaat.
Het idee voor htmx 4 ontstond toen ik besloot om fixi te maken. Hierdoor werd ik vertrouwder met de fetch() API en asynchrone programmering in JavaScript. htmx maakte voorheen altijd gebruik van XMLHttpRequest vanwege problemen met achterwaartse compatibiliteit.
Op een avond werd ik benaderd door Christian, die interessante ideeën had over het streamen van HTML. Dit zette me aan het denken dat het overzetten van de interne werking naar fetch() zaken zou vereenvoudigen, zowel voor hem als voor de bibliotheek in het algemeen. Na wat voorbereiding kregen we Michael en Alex aan boord en ging het project van start.
De ontwikkeling verliep soepel. We begonnen met een poort van fixi samen met de htmx-testsuite. Gaandeweg herontdekten we waarom htmx bepaalde keuzes had gemaakt en brachten we onze nieuwe implementatie steeds dichter bij de oude. Op dit moment zijn de gedragsverschillen tussen 2.x en 4.x relatief klein. Waar ze wel uiteenlopen, hebben we expliciete keuzes gemaakt die htmx-applicaties goed positioneren als webdiensten die 100 jaar mee kunnen gaan.
Let op: we markeren versie 4.0 niet als latest in NPM, omdat we gebruikers die vertrouwen op niet-geversioneerde CDN-URL's niet willen dwingen tot een upgrade. Versie 2.x blijft daarom latest en de 4.0-lijn blijft next tot begin 2027. De website zal echter wel naar 4.0 verwijzen.
Belangrijkste wijzigingen
Vanuit het perspectief van de gebruiker is htmx 4 bijna identiek aan htmx 2. Er zijn echter drie grote wijzigingen:
- Attribuut-overerving is nu standaard expliciet in plaats van impliciet (dit is het belangrijkste punt bij de upgrade).
- Event-namen van htmx zijn gestandaardiseerd en opgeschoond. Gevorderde gebruikers moeten mogelijk de events waar ze naar luisteren aanpassen.
- Geschiedenisondersteuning (History support) maakt standaard geen gebruik meer van
localStorage(wat voorheen veel supportproblemen veroorzaakte). De meeste mensen zullen hier niets van merken.
Intern zijn we overgestapt van XMLHttpRequest naar fetch(), maar dit zou voor de meeste gebruikers transparant moeten zijn.
Attribuut-overerving
In htmx 2 werden veel attributen standaard "geërfd". Hierdoor kon je attributen op ouder-elementen plaatsen, waarna het gedrag ook gold voor de kind-elementen. Dit gedrag, dat stamt uit de tijd van intercooler.js, was geïnspireerd op CSS en werkte dan ook hetzelfde als CSS: krachtig, maar soms moeilijk te begrijpen.
In htmx 4 worden attributen niet meer overgeërfd, tenzij je dit expliciet aangeeft door :inherited achter de attribuutnaam te voegen:
htmx 2 (impliciet):
<div hx-confirm="Weet je het zeker?">
<button hx-delete="/item/1">Verwijderen</button>
</div>
htmx 4 (expliciet):
<div hx-confirm:inherited="Weet je het zeker?">
<button hx-delete="/item/1">Verwijderen</button>
</div>
Dit zal de grootste werklast zijn bij de migratie van htmx 2 naar htmx 4. Om dit te vergemakkelijken, hebben we een command-line tool beschikbaar gesteld om plekken te vinden die als inherited gemarkeerd moeten worden.
Let op: attributen zoals hx-disinherit zijn niet langer nodig en moeten worden verwijderd.
Events (Gebeurtenissen)
De events in htmx 2 waren organisch gegroeid en waren niet goed georganiseerd, waardoor het lastig was om te weten welk event wanneer werd afgevuurd. In htmx 4 volgen alle events nu het patroon htmx:fase:actie[:sub-actie]:
| htmx 2 | htmx 4 |
|---|---|
htmx:beforeRequest | htmx:before:request |
htmx:afterRequest | htmx:after:request |
htmx:beforeSwap | htmx:before:swap |
htmx:afterSwap | htmx:after:swap |
htmx:configRequest | htmx:config:request |
Daarnaast zijn de volgende wijzigingen doorgevoerd:
- De meeste fout-events zijn samengevoegd tot
htmx:error. HTTP-foutresponses activerenhtmx:response:error. - De
htmx:xhr:*events zijn verwijderd, aangezien htmx 4fetch()gebruikt. - De
htmx:validation:*events zijn verwijderd ten gunste van de native browser-formuliervalidatie.
De volledige tabel is te vinden in "What’s New in htmx 4". De command-line upgrade-checker signaleert oude event-namen in hx-on attributen en in JavaScript waar mogelijk.
Geschiedenis (History)
Geschiedenisondersteuning stelt je in staat om acties te implementeren die rekening houden met de terug-knop van de browser. In htmx 2 werd een cache in localStorage gebruikt om pagina's te snapshotten voor herstel. Een grote bron van problemen was dat deze snapshots DOM-mutaties van third-party JavaScript-bibliotheken konden bevatten. Bij herstel van de pagina bleven die mutaties bestaan, maar de onderliggende JavaScript-logica niet.
htmx 4 cached pagina's niet meer in localStorage. Bij terugnavigatie haalt htmx de pagina opnieuw op en swapt deze in de <body>, of in het [hx-history-elt] element als dat aanwezig is. Hierdoor werken third-party bibliotheken in de meeste gevallen gewoon weer, en met goede request-caching is dit zeer snel.
Wie toch lokale caching wenst, kan de volledige hx-history-cache extensie gebruiken. Deze herstelt de geschiedenis vanuit sessionStorage en is ontworpen om goed samen te werken met scripting-oplossingen zoals Alpine.js.
Nieuwe functies
Er zijn twee grote nieuwe functies in htmx 4:
Morph Swaps
We ondersteunen nu "morphing swaps" out-of-the-box. Michael heeft het algoritme van idiomorph verbeterd en naadloos in htmx geïntegreerd.
<hx-partial>
Een andere belangrijke toevoeging is de <hx-partial> tag. Deze tag lijkt op out-of-band swaps, maar is veel duidelijker wanneer je iets wilt doen dat verder gaat dan het simpelweg vervangen van één element door een nieuwe versie van zichzelf:
<hx-partial hx-target="#messages" hx-swap="beforeend">
<div>Nieuw bericht</div>
</hx-partial>
<hx-partial hx-target="#count">
<span>5</span>
</hx-partial>
Extensies
Door de overstap naar fetch() konden we heroverwegen hoe extensies zouden moeten werken. Dit heeft geleid tot de creatie of vernieuwing van diverse extensies, zoals:
hx-preload: laadt content vooraf (bijv. bij mouseover) om requests te versnellen.hx-download: native, opfetchgebaseerde bestandsdownloads.hx-alpine-compat: lost compatibiliteitsproblemen tussen htmx en Alpine.js op.hx-history-cache: cached geschiedenis insessionStoragemet Alpine.js compatibiliteit.
Daarnaast zijn er drie nieuwe of bijgewerkte streaming HTML-extensies:
hx-sse: streamt viatext/event-stream.hx-ws: streamt en verzendt via WebSockets.hx-multipart: streamt viamultipart/mixed.
Tot slot hebben we hx-live ontwikkeld: een eigen front-end scripting-oplossing die nauw integreert met htmx. Het is geïnspireerd door Alpine.js, jQuery en hyperscript, en ondersteunt wat we "DOM-based, HATEOAS-friendly reactivity" noemen.
Voor wie niet zelf wil kiezen uit losse extensies, is er een nieuwe htmax.js bundle beschikbaar waarin htmx samen met de populairste extensies in één bestand is verpakt.
Upgraden
Voor een volledige upgrade-handleiding zie "What’s New in htmx 4". We bieden ook een upgrade-tool aan:
$ npx htmx.org@4.0.0 upgrade-check -- ./templates
Ondersteunde bestandsextensies: .html, .php, .js, .ts, .jinja, .jinja2, .j2, .erb, .hbs (gebruik --ext voor extra extensies, bijv. --ext .vue).
Voorbeeld van output van de tool:
templates/index.html:1: [inheritance] hx-headers needs :inherited suffixtemplates/index.html:3: [renamed-attr] hx-disable -> rename to hx-ignoretemplates/index.html:4: [removed-attr] hx-vars is removed -> use hx-vals with js: prefixtemplates/index.html:9: [old-event] old event name "htmx:afterRequest" -> "htmx:after:request"templates/index.html:9: [old-api] htmx.addClass() is removed -> use element.classList.add()
Er is tevens een "agent skill" beschikbaar om te helpen bij het upgraden.
Installatie
htmx 4.0 kan worden geïnstalleerd via een package manager (versie 4.0.0) of via een CDN:
<script src="https://unpkg.com/htmx.org@4.0.0/dist/htmx.min.js"></script>
Het is tevens direct te downloaden.
LLM's
Omdat veel mensen LLM's gebruiken, bieden we de volgende "skill files" aan voor AI-modellen:
htmx-guidance: kerncompetenties voor ontwikkeling met htmx 4.htmx-debugging: diagnosticeren van htmx-problemen tijdens ontwikkeling.htmx-extension-authoring: schrijven en debuggen van htmx 4 extensies.htmx-upgrade-from-htmx2: migreren van een codebase van htmx 2.x naar 4.x.
Conclusie
We hopen dat jullie genieten van htmx 4. htmx 2 zal onbeperkt ondersteund blijven, dus voel geen druk om direct te upgraden.
Ik wil de volgende mensen bedanken voor hun hulp bij deze release:
- Michael West – Ongelooflijke teamgenoot & grug-brained developer.
- Christian Tanul – Inspiratiebron voor htmx 4 & leider van de streaming & live extensies.
- Alex Petros – Voor het koersvast houden van het schip.
- Stephen Mitchell – Het genie achter de game.
- Stu Kennedy – Onze WebSockets-expert.
- André Ahlert Jr. – Voor de IDE & Editor ondersteuning.
- Dien Hoa Truong – Voor het testen van de vroege htmx 4 en het helpen fixen van vele bugs.
Groetjes,