bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
38.19k stars 1.3k forks source link

Response headers aren't handled when load history from server #1253

Closed mydnicq closed 1 year ago

mydnicq commented 1 year ago

I'm using hx-history="false" directive on one of my elements and when I click browser back it retrieves page elements from the server and not from the htmx-history-cache, which works nicely.

I've also noticed that when htmx loads history from the server it adds the header HX-History-Restore-Request around which I've built a custom logic that adds a response header HX-Location but this header is not handled by the htmx.

I've taken some time and did some research on htmx source code and I found that the loadHistoryFromServer function doesn't check for response headers at all. Was there any particular reason to handle XMLHttpRequest differently than the handleAjaxResponse function for instance?

delaneyj commented 1 year ago

I'm having a similar issue if the page is loaded directly from a deep link. Shouldn't htmx on load check for response headers and not just on ajax response?

1cg commented 1 year ago

When navigating back via history, the navigation is treated as a "full page load" just like if you clicked back in the browser, so no htmx header processing is done, as with links. This is intended behavior (since if the user hits refresh on the same URL, you would see the same behavior.)

I'm willing to discuss handling headers but, as of now, this is functioning as designed.

mydnicq commented 1 year ago

@1cg thx for the explanation. I came to the same conclusion when I was reading the code. But then I found that header HX-History-Restore-Request and thought what if I use the header to implement a conditional logic when rendering the response based on my business requirements? If loadHistoryFromServer would use the same HX-Request header then it would be more clear that in that case I just need to prepare the same response as I did for the very first - initial request. So in terms of REST, the first request returned a particular resource and the second instead of using the browser cache should return the same resource from the server. This is how the current logic works and it makes total sense. However, as I said, the different request header confused me.

My personal opinion about this is, that even though semantically and logically seems the current solution perfectly fine, my understanding of REST is, that if the remote state has changed when the user goes from page 1 to page 2 and then hits the browser back, the option that htmx provides with hx-history=false leads to situations as I have faced. which means that I'm aware of the possible change on the remote state and that's why I want to return a different response. In my particular case, it's even more clear that using the HX-Location header as a response to loadHistoryFromServer wants the user to redirect to page 2 because page 1 shouldn't be presented because the remote state doesn't allow this. The same happens when the user hits refresh, I'm returning 302 and user lands on page 2.

I've also tested handling headers in the loadHistoryFromServer and it works without any problems. I didn't want to open a PR because I assumed the current logic is by design. However, I'm willing to open it if you want.