- Die Leute sprechen über htmx, als würde es das Web vor SPAs retten
- Der htmx-Erfinder Carson Gross beschreibt diese Dynamik augenzwinkernd als „hegelsche Dialektik“:
- These: traditionelle MPA
- Antithese: SPA
- Synthese: eine Anwendung aus interaktiven, hypermedienbasierten Inseln
- Ich habe das allerdings nicht gesehen und vor einiger Zeit einfach „eine SPA mit htmx gebaut“
- Es ist ein PoC einer einfachen ToDo-Listen-App
- Nach dem Laden der Seite kommuniziert sie nicht mehr mit dem Server
- Alles wird lokal auf dem Client verarbeitet
- Wenn htmx darauf ausgerichtet ist, den Hypermedia-Austausch über das Netzwerk zu verwalten, wie funktioniert das dann?
- Ein einfacher Trick: Der „serverseitige“ Code läuft im Service Worker
Service Worker
- Er fungiert als Proxy zwischen der Webseite und dem Internet
- Er kann Netzwerkanfragen abfangen und manipulieren
- Er kann Anfragen verändern, Antworten für die Offline-Nutzung cachen und neue Antworten erzeugen, ohne Anfragen aus dem Browser herauszusenden
- Diese letzte Fähigkeit ist der Kern dieser Single-Page-App
- Wenn htmx eine Netzwerkanfrage auslöst, fängt der Service Worker sie ab
- Anschließend führt der Service Worker die Business-Logik aus und erzeugt neues HTML
- htmx tauscht das neue HTML im DOM aus
Vorteile gegenüber einer herkömmlichen SPA
- Der Service Worker muss IndexedDB als Speicher verwenden
- Dadurch bleibt der Zustand zwischen Seitenladungen erhalten
- Selbst wenn man die Seite schließt und später zurückkehrt, merkt sich die App die Daten
- Das ist ein zusätzlicher Vorteil, den man bei dieser Architektur „gratis“ bekommt
- Es ist leicht, die App auch offline lauffähig zu machen
Nachteile
- Die Unterstützung durch die Developer Tools ist schwach
console.log fehlt gelegentlich
- Die Anzeige, ob der Service Worker installiert ist, ist nicht zuverlässig
- Fehlende ES-Modul-Unterstützung in Firefox
- Der gesamte Code muss in einer einzigen Datei untergebracht werden
- Die allgemeine Developer Experience ist „nicht besonders spaßig“
Trotzdem funktioniert eine htmx-SPA gut
Implementierungsdetails
- Das Basis-HTML ist ein leeres Gerüst für die Single-Page-App
- Das
<body>-Tag richtet mit htmx den eigentlichen App-Inhalt ein
hx-boost="true": weist htmx an, Antworten auf Link-Klicks und Formular-Submits per Ajax auszutauschen, ohne vollständige Seitennavigation
hx-push-url="false": verhindert, dass htmx bei Link-Klicks und Formular-Submits die URL ändert
hx-get="./ui": weist htmx an, beim Laden der Seite die Seite von /ui zu holen und auszutauschen
hx-target="body": weist htmx an, das Ergebnis in das <body>-Element einzusetzen
hx-trigger="load": weist htmx an, all das beim Laden der Seite auszuführen
/ui-Endpunkt
- Gibt das eigentliche Markup der App zurück
- Danach übernimmt htmx Links und Formulare und macht sie interaktiv
- Der Service Worker übernimmt das Request-Routing mit einer Bibliothek im Express-Stil
setFilter und listTodos sind einfache Funktionen, die IDB Keyval kapseln
- Die
App-Komponente besteht aus Filter-Formular, ToDo-Liste und Hinzufügen-Formular
/todos/add-Endpunkt
- Speichert das ToDo und gibt eine Antwort mit erneut gerendertem UI zurück
- htmx tauscht die Antwort im DOM aus
Todo-Komponente
- Besteht aus Checkbox, Löschen-Button und ToDo-Text
- Die Checkbox löst eine Anfrage an
/todos/${id}/update aus
- Der Löschen-Button löst eine Delete-Anfrage an
/todos/${id} aus
- Der ToDo-Text hat zwei Zustände: „normal“ und „editing“
- htmx lauscht auf das Double-Click-Event
- Anfrage an
/ui/todos/${id}?editable=true
- Der Service Worker gibt
Todo-HTML mit einem <input> zurück
- htmx ersetzt den aktuellen ToDo-Eintrag durch das HTML aus der Antwort
Zusammenfassung
- Technisch funktioniert es
- Ist es eine gute Idee? Ist es wirklich der Höhepunkt hypermedienbasierter Apps? Sollte man React aufgeben und so bauen?
- Bei vollständig lokalen Apps fühlt sich die Indirektheit von htmx eher belastend als befreiend an
- Die meisten Apps sind nicht vollständig lokal
- Das Muster der „interaktiven Inseln“ scheint besser zu sein, als „serverseitigen“ Code zwischen Service Worker und echtem Server aufzuteilen
- Es war ein experimenteller Versuch zu zeigen, wie man mit Hypermedia eine vollständig lokale Single-Page-App bauen kann
Noch keine Kommentare.