Response from HX-Location should respect HX-Push-Url header
I have a scenario where I set the HX-Location header to redirect the client to other page (assume /x). In some cases, the response (of /x) could contain HX-Push-Url header (assume /y) which is not being respected, i.e., the page url is still same as the url in HX-Location header (/x).
Is there a way to push the url in HX-Push-Url (/y) header of response in browser history after the redirect using HX-Location header?
From what I see in the sources:
https://github.com/bigskysoftware/htmx/blob/e0905ff94a3623f6383278bf2ea740c65b616105/src/htmx.js#L4692-L4694 https://github.com/bigskysoftware/htmx/blob/e0905ff94a3623f6383278bf2ea740c65b616105/src/htmx.js#L4703-L4705
I don't see any reason HX-Push-Url would not be applied from the second endpoint's response, however it looks like htmx ignores whether the redirected endpoint submitted any instruction about pushing a URL or not, and uses pushUrlIntoHistory after the request is made to push the redirected URL anyway
So, I would expect your history to actually contain the URL sent back by your second endpoint's HX-Push-Url header as you would expect, but likely one step backwards in the history (which would be an issue of course).
Could you confirm if this is actually what is happening? Do you see the desired URL when going back in the history by 1 step? If so, we can likely add a fix for that
also see #3045 for more detail on the cause
The issue is the ajaxHelper function is waits to complete fully as a promise which will push the hx-push-url to history and 'then' it will push the hx-location URL every time. We could add
ajaxHelper('get', redirectPath, redirectSwapSpec).then(function() {
if (!redirectSwapSpec?.noPushUrl) pushUrlIntoHistory(redirectPath)
})
to add a new optional key to hx-location data spec that if set true would block the post request push if required.
Maybe a better way would be this
const oldPath = currentPathForHistory
ajaxHelper('get', redirectPath, redirectSwapSpec).then(function() {
if (oldPath === currentPathForHistory) pushUrlIntoHistory(redirectPath)
})
Could you confirm if this is actually what is happening? Do you see the desired URL when going back in the history by 1 step? If so, we can likely add a fix for that
Yes. I can see the desired URL if I go one step back.
could another solution be to add a pushUrl optional boolean to HtmxAjaxHelperContext and HtmxAjaxEtc and HtmxResponseInfoand then allow ajaxHelper to pass this through with the request config and then set this true for all hx-location requests. Then get the ajax request to push history at the end if this is true by using this boolean in the determineHistoryUpdates function. This new option would also resolve #3114 as there would then be a proper ajax api to push url.
added a possible PR that has a proper fix for this bug