HTMX - History Support



HTMX is a powerful library that allows developers to access modern browser's feature(Browser History API) directly from HTML without using extensive JavaScript.

How htmx history support work?

Below mentioned steps will guide you, on how htmx history support works on the browsers.

Step 1: If you want an element to push its request URL into the browser navigation bar to add the current state of the page into the browser history then you have to use hx-push-url attribute. If the user clicks on the link then htmx will store the current DOM before the request gets to the /content. Then it will swap and push a new location into the history stack of the browser.

<a hx-get="/content" hx-push-url="true">Content</a>

Step 2: If the user hit the browser's back button then the previous content will be restored, simulating 'going back' to the previous state from the cache.

Step 3: If the address is accessible from teh cache then it will request an Ajax request HX-History-Restore-Request set to true and ask for the whole webpage from the HTML. Or it will set htmx.config.refreshOnHistoryMiss is set to true so the hard browser refresh can be performed.

Specifying History Snapshot Element

It is a default behavior of htmx to use the body to take and store the history snapshot. If you want to narrow it down to keep the snapshot of a particular element then you can use the hx-history-elt attribute to specify the specific element. You just need to be sure that this element should be existing on all the pages or restoring from history won't work.

Undoing DOM Mutations By 3rd Party Libraries

You have to clean the DOM before snapshot is taken when you are planning to use a 3rd party library and want to use the htmx history support feature.

Let's assume a case where "Tom Select" (a 3rd party library), makes select elements a much richer UX. And set up Tom Select to turn any input element with .tomselect class into a rich element. Initializing elements that have the class in new content. If the .tomselect class is on any element then all those input elements are rich selectors.

htmx.onLoad(function (target) {
 // find all elements in the new content that 
 // should be an editor and init w/ TomSelect
 var editors = target.querySelectorAll(".tomselect")
 .forEach(elt => new TomSelect(elt))
});

This will merge the DOM and if you don't want to merge to save to the history cache, since TomSelect will be reinitialized when the history content is loaded back into the screen. To deal with this, you need to catch the htmx:beforeHistorySave event and clean out the TomSelect mutations by calling destroy() function on them.

htmx.on('htmx:beforeHistorySave', function() {
 // find all TomSelect elements
 document.querySelectorAll('.tomSelect')
 // and call destroy() on them
 .forEach(elt => elt.tomselect.destroy()) 
})

Disabling History Snapshots

If we set false value on htmx-history attribute on any element in the current document or any html fragment loaded into the current document via htmx then history snapshotting will be disabled. This can be used to stop sensitive data from entering into the localStorage cache.

Sensitive data in the localStorage cache is important for shared-use or public computers. But the history navigation will work as it is just a restoration of the URL that will be requested from the server.

Advertisements