Passer au contenu

Support de l’historique

Htmx fournit un mécanisme simple pour interagir avec l’API de l’historique du navigateur :

Si vous souhaitez qu’un élément donné pousse son URL de requête dans la barre de navigation du navigateur et ajoute l’état actuel de la page à l’historique du navigateur, incluez l’attribut hx-push-url :

<a hx-get="/blog" hx-push-url="true">Blog</a>

Lorsqu’un utilisateur clique sur ce lien, htmx prendra un instantané du DOM actuel et le stockera avant de faire une requête à /blog. Il fait ensuite le swap et pousse une nouvelle position dans la pile d’historique.

Lorsque l’utilisateur appuie sur le bouton retour, htmx récupérera l’ancien contenu du stockage et le remettra dans la cible, simulant le « retour » à l’état précédent. Si l’emplacement n’est pas trouvé dans le cache, htmx fera une requête AJAX à l’URL donnée, avec l’en-tête HX-History-Restore-Request défini sur true, et s’attendra à recevoir le HTML nécessaire pour toute la page. Alternativement, si la variable de configuration htmx.config.refreshOnHistoryMiss est définie sur true, il effectuera un rafraîchissement complet du navigateur.

REMARQUE : Si vous poussez une URL dans l’historique, vous devez pouvoir naviguer vers cette URL et obtenir une page complète ! Un utilisateur pourrait copier et coller l’URL dans un e-mail ou un nouvel onglet. De plus, htmx aura besoin de toute la page lors de la restauration de l’historique si la page n’est pas dans le cache de l’historique.

Spécification de l’élément d’instantané d’historique

Par défaut, htmx utilisera le body pour prendre et restaurer l’instantané d’historique. C’est généralement la bonne chose à faire, mais si vous voulez utiliser un élément plus restreint pour l’instantané, vous pouvez utiliser l’attribut hx-history-elt pour en spécifier un différent.

Attention : cet élément devra être présent sur toutes les pages sinon la restauration depuis l’historique ne fonctionnera pas de manière fiable.

Annuler les mutations DOM par des bibliothèques tierces

Si vous utilisez une bibliothèque tierce et souhaitez utiliser la fonction d’historique htmx, vous devrez nettoyer le DOM avant qu’un instantané ne soit pris. Prenons l’exemple

de la bibliothèque Tom Select, qui rend les éléments select beaucoup plus riches en termes d’expérience utilisateur. Configurons TomSelect pour transformer tout élément d’entrée avec la classe .tomselect en un élément select riche.

Tout d’abord, nous devons initialiser les éléments ayant la classe dans le nouveau contenu :

htmx.onLoad(function (target) {
// trouver tous les éléments dans le nouveau contenu qui devraient être
// un éditeur et initier avec TomSelect
var editors = target.querySelectorAll(".tomselect")
.forEach(elt => new TomSelect(elt));
});

Cela créera un sélecteur riche pour tous les éléments d’entrée ayant la classe .tomselect. Cependant, cela mutera le DOM et nous ne voulons pas que cette mutation soit enregistrée dans le cache d’historique, puisque TomSelect sera réinitialisé lorsque le contenu de l’historique sera rechargé dans l’écran.

Pour gérer cela, nous devons capturer l’événement htmx:beforeHistorySave et nettoyer les mutations de TomSelect en appelant destroy() sur eux :

htmx.on('htmx:beforeHistorySave', function () {
// trouver tous les éléments TomSelect
document.querySelectorAll('.tomSelect')
.forEach(elt => elt.tomselect.destroy()) // et appeler destroy() sur eux
});

Cela rétablira le DOM à l’HTML d’origine, permettant ainsi un instantané propre.

Désactiver les instantanés d’historique

La capture d’instantanés d’historique peut être désactivée pour une URL en définissant l’attribut hx-history sur false sur tout élément du document actuel, ou sur tout fragment HTML chargé dans le document actuel par htmx. Cela peut être utilisé pour empêcher l’entrée de données sensibles dans le cache localStorage, ce qui peut être important pour les ordinateurs à usage partagé/public. La navigation dans l’historique fonctionnera comme prévu, mais lors de la restauration, l’URL sera demandée au serveur au lieu du cache local d’historique.