htmx icon indicating copy to clipboard operation
htmx copied to clipboard

No standard way of triggering a boosted refresh

Open nimaaskarian opened this issue 8 months ago • 3 comments

I want to refresh the page user is in with htmx after a put request.

having a div with contents (or body itself), with hx-trigger="refresh-page" and correct target and swap values, and sending HX-Trigger: refresh-page` header, makes the scrollbar reset (jumps to the top).

I have to have a ?redirect=/url param for the put request, which I think it could be avoided if hx-trigger worked without reseting the scroll bar.

Or like a weird child of HX-Location and HX-Refresh, there was a standard way of boost-refreshing the page. Something like HX-Refresh-Boosted: true

nimaaskarian avatar Mar 18 '25 07:03 nimaaskarian

I think if you use https://htmx.org/headers/hx-location/ you can use set the swap in your HX-Location header. If you set this the same as you would use on a scroll targeting boosted link it should work exactly how you want.

HX-Location: {"path":"/test2", "swap":"innerHTML scroll:#someid:top"}

MichaelWest22 avatar Mar 18 '25 20:03 MichaelWest22

I think if you use https://htmx.org/headers/hx-location/ you can use set the swap in your HX-Location header. If you set this the same as you would use on a scroll targeting boosted link it should work exactly how you want.

HX-Location: {"path":"/test2", "swap":"innerHTML scroll:#someid:top"}

I think I explained the problem a bit confusingly.

HX-Location works fine, tho it needs the query param ?redirect=url in my case. The scroll reset behavior was found using HX-Trigger only.

Multiple routes can send the same put request to the server, which they all needed to be updated afterwards; I had to pass the url of my routes to their html as a query param, only to send it back to the put request's route so then that would trigger a refresh using the HX-Location header.

nimaaskarian avatar Mar 19 '25 06:03 nimaaskarian

It should also be possible if you have your refresh element like

<div hx-get="" hx-trigger="refresh-page" hx-swap="innerHTML scroll:#someid:top" hx-target="body"></div>

That will perform the body swap with a custom scroll position but for this to work all the information of how to perform the refresh-swap must already be pre-loaded onto the page earlier.

It is often the case that you can instead know all the details of where you want to drive the end user on the backend server and this is where HX-Location header is a good option to just add optionally with all the info you have on the server at the time from the last request to take the end user to the right location. Also remember to check out all the various HX-* request headers like HX-Current-URL, HX-Target and HX-Trigger as these headers can give you the extra information you need when the htmx put request comes in to decide If and how to return a HX-Location response header.

If you need more complete control than what HX-Location provides then you can return a HX-Trigger response header with a custom event message and then instead of using a simple hx-trigger="refresh-page" standard htmx elements to perform the custom action you can add a very simple event listener on body with a few lines of JS that will perform any action required and the advantage here is that this custom JS can combine both data from the hx-trigger message plus lookup state on the DOM before picking its next step.

document.body.addEventListener("refresh-page", function(evt){
  // check if last-refresh timestamp in hidden input is older than 2 min before refreshing
  if ( (new Date()).getTime() - (Number(document.getElementById('last-refresh')?.value) || 0) > 120000 ) {
    htmx.ajax('GET', evt.detail.refreshUrl, {target:'body', swap:`innerHTML scroll:#${evt.detail.scrollToId}:top`})
  }
})

Another Option in htmx is to make use of one of the many htmx events like htmx:afterSwap and by adding an event listener on this event you can check if the response has just come back from one of your put requests and use the response data and page data to decide when and how to do your custom refresh.

MichaelWest22 avatar Mar 19 '25 10:03 MichaelWest22