1. Requête GET simple hx-get
Le clic sur le bouton déclenche une requête GET vers le serveur.
La réponse HTML renvoyée remplace le contenu de l'élément ciblé par hx-target
(ici #hello-result), grâce à hx-swap="innerHTML" (valeur par défaut).
Un indicateur de chargement (hx-indicator) s'affiche pendant la requête.
<button hx-get="index.php?action=hello"
hx-target="#hello-result"
hx-indicator="#hello-spinner">
Dire bonjour au serveur
</button>
2. Recherche en direct hx-trigger + delay
À chaque frappe (keyup), une requête est envoyée après 500ms
sans nouvelle frappe (delay:500ms) — ça évite de spammer le serveur.
hx-trigger="keyup changed delay:500ms" combine trois conditions.
Le contenu de l'input est envoyé automatiquement comme paramètre q car
c'est un champ <input> dans le périmètre de la requête.
<input type="text" name="q"
hx-get="index.php?action=search"
hx-trigger="keyup changed delay:500ms"
hx-target="#search-results">
3. Validation en temps réel hx-get sur un champ
Le champ email valide côté serveur (PHP) à chaque changement de focus (blur),
sans recharger la page ni soumettre tout le formulaire. Utile pour de la validation
"vraie" (unicité en base, format métier…) impossible à faire en JS pur.
<input type="email" name="email"
hx-get="index.php?action=validate-email"
hx-trigger="blur, keyup changed delay:400ms"
hx-target="#email-hint">
<span id="email-hint"></span>
4. Ajouter / supprimer des éléments hx-swap="beforeend" / outerHTML
"Ajouter" fait un POST et insère la réponse à la fin de la liste
(hx-swap="beforeend") sans toucher au reste. "Supprimer" fait un DELETE
sur l'élément lui-même et le remplace par une réponse vide via hx-swap="outerHTML",
ce qui le fait disparaître du DOM.
<button hx-post="index.php?action=add-item"
hx-target="#item-list"
hx-swap="beforeend">+ Ajouter</button>
<li>Élément
<button hx-delete="index.php?action=delete-item"
hx-target="closest li"
hx-swap="outerHTML">✕</button>
</li>
- Élément initial
5. Confirmation avant envoi hx-confirm
hx-confirm affiche une boîte de dialogue native avant d'envoyer la requête.
Si l'utilisateur clique "Annuler", aucune requête n'est envoyée.
<button hx-delete="index.php?action=confirmed-delete"
hx-confirm="Vraiment supprimer ?"
hx-target="#confirm-result">
Supprimer le compte
</button>
6. Polling automatique hx-trigger="every 3s"
L'élément relance automatiquement une requête toutes les 3 secondes tant qu'il est dans le DOM — pratique pour un statut de job, une barre de progression, un chat… Aucune boucle JS à gérer.
<div hx-get="index.php?action=poll-status"
hx-trigger="every 3s">
...
</div>
7. Onglets chargés à la demande hx-get + hx-target partagé
Chaque bouton charge le contenu de son onglet uniquement au clic (pas tout chargé
d'avance). Tous ciblent la même zone #tab-content. La classe active
est gérée par HTMX via hx-on::after-request pour illustrer qu'on peut
quand même ajouter un peu de logique JS ciblée si besoin.
<button hx-get="index.php?action=tab&name=a"
hx-target="#tab-content">Onglet A</button>
Contenu de l'Onglet A. Chargé via hx-get au clic.
🚀 Cas avancés
8. Mise à jour "hors bande" hx-swap-oob
Une seule requête/réponse peut mettre à jour plusieurs zones
différentes de la page. Le bouton cible la liste normalement, mais la réponse
du serveur contient en plus un fragment marqué hx-swap-oob="true"
qui va se placer tout seul dans l'élément portant le même id ailleurs sur
la page (ici, le compteur en haut) — sans passer par hx-target.
<!-- réponse serveur pour un seul clic -->
<li>Élément #4 <button hx-delete="...">✕</button></li>
<span id="oob-counter" hx-swap-oob="true">
4 élément(s)
</span>
Compteur (ailleurs dans le DOM) : 1 élément(s)
9. Éviter les réponses dans le désordre hx-sync
Le serveur simule ici un délai aléatoire (200 à 1800ms). Sans synchronisation, si tu
tapes vite, une réponse lente à une frappe ancienne pourrait arriver
après une réponse plus récente et écraser le bon résultat par un résultat
obsolète. hx-sync="this:replace" annule automatiquement la requête en
cours dès qu'une nouvelle est déclenchée sur le même élément : seule la dernière
réponse compte.
<input name="q"
hx-get="index.php?action=sync-search"
hx-trigger="keyup changed delay:100ms"
hx-sync="this:replace"
hx-target="#sync-result">
10. N'extraire qu'un fragment de la réponse hx-select
Le serveur renvoie volontairement 3 blocs, mais grâce à hx-select, HTMX
n'insère dans la page que celui dont le sélecteur CSS correspond — pratique pour
réutiliser un endpoint qui rend "une page complète" (avec header/footer) tout en
n'injectant qu'un extrait précis côté client.
<button hx-get="index.php?action=select-fragment"
hx-select="#useful-part"
hx-target="#select-result">
Charger seulement le bloc utile
</button>
11. Temps réel avec Server-Sent Events hx-ext="sse"
Le serveur ouvre un flux text/event-stream et pousse des évènements au fil
de l'eau ; HTMX les injecte dans le DOM au fur et à mesure, sans polling côté client.
Utile pour des notifications, une progress bar, un flux de logs… La démo s'arrête après
6 évènements et envoie un évènement close explicite pour éviter que le
navigateur ne reconnecte tout seul (comportement par défaut d'EventSource).
Elle démarre au clic, pas au chargement de la page : le serveur PHP
intégré est mono-thread, donc une connexion ouverte en arrière-plan bloquerait toutes
les autres démos de la page tant qu'elle n'est pas terminée.
<div hx-ext="sse" sse-connect="index.php?action=sse-stream">
<div sse-swap="tick" hx-swap="beforeend"></div>
</div>
12. Navigation façon SPA hx-push-url
Chaque lien charge un fragment de contenu et met à jour l'URL du
navigateur (hx-push-url="true") sans rechargement complet. Le bouton
retour du navigateur fonctionne normalement. En production, le serveur doit aussi
savoir répondre correctement si quelqu'un charge cette URL directement (rafraîchit la
page) — typiquement en inspectant l'en-tête HX-Request pour renvoyer soit
la page complète, soit juste le fragment.
<a hx-get="index.php?action=page&name=about"
hx-target="#spa-content"
hx-push-url="true">À propos</a>
📌 Ce qu'il faut retenir
HTMX étend le HTML avec des attributs (hx-get, hx-post,
hx-put, hx-delete, hx-trigger, hx-target,
hx-swap, hx-confirm, hx-indicator…). Le serveur renvoie
des fragments HTML (pas du JSON) qui remplacent ou complètent une partie
du DOM. Résultat : des interfaces dynamiques avec très peu (voire zéro) JavaScript custom,
et toute la logique métier reste côté serveur (ici, en PHP).