Closed jurrid closed 8 months ago
Could you share the OS/Browser you're using?
Sure;
Wondering if this is related to https://github.com/inertiajs/inertia/issues/721 and if there's really any way at all we can control history navigation.
When I read it, it seems highly related! I'll conduct some testing on my end to see if it's possible in plain HTML and Javascript. I've done it previously with Vue Router, but that's not utilized with Inertia.
I have developed a sample application to illustrate the possibility of blocking the back button, along with some accompanying notes.
You can access the sample app at the following link: https://plankton-app-cm9rj.ondigitalocean.app
The code used on the create page:
window.addEventListener("load", (e) => {
window.history.pushState({}, null, null);
});
window.addEventListener("popstate", (e) => {
if (!confirm("Do you really want to leave?")) {
e.preventDefault();
window.history.pushState({}, null, null);
} else {
history.back();
}
});
In Firefox, the functionality behaves as expected. However, in Chrome, interaction with the browser element is necessary to trigger the window.onpopstate function. Another peculiar behavior in Chrome is that after declining the confirmation and subsequently pressing the back button again, the browser does not prompt the confirmation dialog for the second time. To trigger the confirmation dialog for the second time, it is necessary to interact with the browser element once more.
Safari on macOS fails to trigger any functionality, making it a mystery as to what is happening.
Although I believe it is somehow possible, I may overlook the implications of window.history.pushState({}, null, null)
for Inertia; that must be executed, along with the peculiar behavior observed in Safari and Chrome.
As of now, the quickest approach would be to adding a note into the documentation addressing this behavior.
Thanks @jurrid. I'll leave this one open but we'd also appreciate a PR to the docs for confirm
about this.
Hey I haven't read through everything here, but just thought I'd mention that the browser does not allow cancelling popstate events:
https://stackoverflow.com/questions/32432296/is-it-possible-to-e-preventdefault-in-window-onpopstate
https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event
Hi @reinink ,
Thank you for taking the time to read this far. I understand that the event is non-cancelable. My assumption is that messing with the history state will have some effect.
Perhaps you could provide some insight into this matter: Filamentphp utilizes the window.onbeforeunload
JavaScript function, as demonstrated on their demo application. When I incorporate this code directly into a plain HTML page, it functions properly(page refresh, back button, etc). However, when implemented within an Inertia page, it fails to work with the back button. Interestingly though, upon page refresh, the message is displayed.
onMounted(() => {
window.onbeforeunload = function () {
return "Data will be lost if you leave the page, are you sure?";
};
});
That is because an window.onbeforeunload
event isn't triggered, it would only trigger on fresh page visits (as is the case with multi-page apps, such as Filament). For an SPA that even wouldn't be triggered, the page isn't unloaded.
Yup, exactly @RobertBoes. Basically browsers make cancelling forward/back navigation events really difficult as otherwise these APIs could be abused by malicious websites. From what I understand even window.onbeforeunload
has really strict rules around it and should only be used to warn people about unsaved changes. See here: https://developer.chrome.com/docs/web-platform/page-lifecycle-api#the_beforeunload_event
Alright, that makes sense. But what about when you hit the refresh button? Technically, the page isn't reloaded at that point and remains in SPA mode, or am I overlooking something?
Nah in that case it doesn't do an "SPA refresh", it does a full page reload, so it's effectively the same thing as visiting a different page.
Alright, thanks everyone for the information!
So is the general consensus here that this is simply technically not possible? If so I feel that a note the docs is required and this can be closed.
@driesvints I've added a note to the docs: https://github.com/inertiajs/inertiajs.com/commit/0cd3b20044f2aa0f9ffc983bf03aa26a24588607
Technically the popstate
event is a native browser event and not an Inertia event, so in that sense kind of doesn't make sense to include in the Inertia event docs, but given their close connection it's probably helpful to include this note either way.
Version:
@inertiajs/vue3
version: "^1.0.15"Describe the problem:
The documentation provides an example of canceling events. When navigating away within the application, the confirm message is displayed. Declining to navigate away works perfectly in this scenario. However, when using the browser's back button, although the confirm message appears, declining it leads to the browser redirecting away, which is not the desired behavior.
Steps to Reproduce:
Utilize the examples provided at: https://inertiajs.com/events#cancelling-events