Back

UX en temps réel avec l'extension SSE de htmx

UX en temps réel avec l'extension SSE de htmx

La plupart des applications web ont besoin de mises à jour en direct à un moment donné — un badge de notification, une barre de progression, un tableau de bord qui se rafraîchit sans polling. La réponse habituelle est d’utiliser les WebSockets ou un framework SPA complet. Mais si vous utilisez déjà htmx, il existe une approche plus simple : l’extension SSE de htmx, qui connecte les événements envoyés par le serveur directement dans votre HTML avec presque aucun JavaScript.

Points clés à retenir

  • Les Server-Sent Events (SSE) fournissent un flux unidirectionnel du serveur vers le client via HTTP standard — idéal pour les notifications, tableaux de bord et flux en direct.
  • L’extension SSE de htmx est un package séparé (htmx-ext-sse) qui connecte les flux SSE à votre HTML en utilisant des attributs déclaratifs, sans nécessiter de JavaScript personnalisé.
  • Trois attributs principaux — sse-connect, sse-swap et hx-trigger="sse:<event>" — couvrent la plupart des patterns d’UX en temps réel.
  • SSE est plus simple à déployer que les WebSockets et élimine les requêtes inutiles du polling, bien qu’il ne supporte que la communication serveur vers client.

Ce que sont réellement les Server-Sent Events

Les Server-Sent Events (SSE) constituent un protocole natif du navigateur pour le streaming unidirectionnel du serveur vers le client via une connexion HTTP standard. Le serveur maintient la connexion ouverte et envoie des événements textuels chaque fois qu’il a quelque chose à communiquer. Le navigateur les reçoit via l’API EventSource.

Le format sur le réseau est du texte brut :

event: priceUpdate
data: <li>BTC — 62 400 $</li>

Chaque événement possède un nom optionnel et une charge utile data. Plusieurs lignes data: sont concaténées. Les événements sont séparés par une ligne vide.

Comme SSE fonctionne sur HTTP, il traverse les proxies et pare-feu sans configuration spéciale. Il prend en charge la reconnexion automatique nativement. Le compromis concerne la directionnalité : une fois la connexion ouverte, le client ne peut pas renvoyer de messages. Pour les notifications, tableaux de bord, progression de tâches et flux en direct, c’est parfaitement adapté. Pour le chat ou l’édition collaborative, vous auriez besoin des WebSockets à la place.

Installation de l’extension SSE de htmx

Le support SSE n’est pas intégré au cœur de htmx. Il se trouve dans le package séparé htmx-ext-sse. Chargez les deux scripts et activez l’extension sur un élément conteneur :

<head>
  <script  src="https://cdn.jsdelivr.net/npm/htmx.org@latest/dist/htmx.min.js"></script>  
  <script  src="https://cdn.jsdelivr.net/npm/htmx-ext-sse@latest"></script>
</head>
<body hx-ext="sse">

Pour les builds basés sur npm, installez avec npm install htmx-ext-sse et importez à la fois htmx.org et htmx-ext-sse dans votre fichier d’entrée.

Note : L’ancien attribut hx-sse des versions antérieures de htmx est obsolète. Utilisez hx-ext="sse" avec l’extension dédiée à la place.

Attributs principaux pour les mises à jour en streaming avec htmx

Trois attributs couvrent la plupart des patterns d’UX en temps réel :

AttributObjectif
sse-connect="<url>"Ouvre la connexion EventSource
sse-swap="<nom-événement>"Remplace le contenu de l’élément par le HTML entrant
hx-trigger="sse:<nom-événement>"Déclenche une requête htmx lorsque l’événement arrive

Un flux en direct qui remplace son propre contenu à chaque envoi :

<div hx-ext="sse" sse-connect="/feed" sse-swap="message">
  Chargement…
</div>

Le serveur envoie un événement avec data: <p>Nouvel élément</p> suivi d’une ligne vide, et htmx remplace le contenu du div — aucun JavaScript requis.

Gestion de plusieurs événements et déclenchement de requêtes

Un seul sse-connect peut alimenter plusieurs éléments enfants, chacun écoutant un nom d’événement différent :

<div hx-ext="sse" sse-connect="/stream">
  <div sse-swap="statsUpdate"></div>
  <div sse-swap="alertBanner"></div>
</div>

Vous pouvez également utiliser les événements SSE pour déclencher des requêtes HTTP de suivi plutôt que de remplacer directement le contenu. Ceci est utile lorsque l’événement signale que de nouvelles données sont disponibles mais que vous souhaitez que htmx récupère le fragment complet rendu :

<div hx-ext="sse" sse-connect="/events">
  <div hx-get="/notifications" hx-trigger="sse:newNotification">
    <!-- rafraîchi à chaque événement SSE -->
  </div>
</div>

Pour fermer un flux proprement lorsque le serveur signale la fin, ajoutez sse-close="done" — la connexion se ferme lorsqu’un événement nommé done arrive.

Quand SSE surpasse le polling ou les WebSockets

  • vs. polling : SSE élimine les requêtes inutiles. Le serveur envoie uniquement lorsque quelque chose change.
  • vs. WebSockets : SSE est plus simple à déployer, fonctionne sur HTTP/1.1 et HTTP/2, et ne nécessite aucune infrastructure serveur spéciale. Utilisez les WebSockets uniquement lorsque vous avez besoin d’une communication bidirectionnelle.

Une note pratique : les navigateurs en HTTP/1.1 limitent les connexions par domaine à six. Si les utilisateurs ouvrent plusieurs onglets, les connexions SSE se disputent cette limite. Le service via HTTP/2 évite largement cette limitation en multiplexant plusieurs flux sur une seule connexion.

Conclusion

L’extension SSE de htmx vous permet d’ajouter une véritable interface utilisateur en temps réel HTML-over-the-wire — tableaux de bord en direct, indicateurs de progression, flux de notifications — avec quelques attributs HTML et un endpoint serveur qui sait maintenir une connexion ouverte. Aucune bibliothèque de gestion d’état, aucun routage côté client, aucun pipeline de build requis. Si votre serveur peut diffuser du texte, votre interface peut être en direct.

FAQ

Non. Les Server-Sent Events sont strictement unidirectionnels, du serveur vers le client. Si vous devez renvoyer des données, associez votre flux SSE avec des requêtes htmx standard en utilisant hx-post ou hx-put. Pour une communication entièrement bidirectionnelle, comme le chat en temps réel, les WebSockets constituent le meilleur choix.

L'API EventSource intégrée au navigateur tente automatiquement de se reconnecter après un bref délai. Le serveur peut contrôler l'intervalle de nouvelle tentative en incluant un champ retry dans le flux d'événements. L'extension SSE de htmx hérite de ce comportement de reconnexion sans aucune configuration supplémentaire de votre part.

Oui, et HTTP/2 est d'ailleurs recommandé. Sous HTTP/1.1, les navigateurs limitent les connexions concurrentes par domaine à environ six, donc plusieurs onglets avec des flux SSE ouverts peuvent épuiser cette limite. HTTP/2 multiplexe les flux sur une seule connexion, supprimant effectivement cette limite.

Envoyez un événement nommé qui correspond à la valeur de l'attribut sse-close sur votre élément conteneur. Par exemple, si vous définissez sse-close égal à done, l'envoi d'un événement avec le nom done entraînera la fermeture propre de la connexion EventSource côté client par l'extension.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay