-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Describe the problem
I've been thinking a lot about the beforeNavigate interface, as you can see by my recent issues:
- We can't access goto props during beforeNavigate #8605
- beforeNavigate doesn't trigger default browser behaviour as-per the docs #8597
- beforeNavigate shouldn't trigger when <a target="_blank"> #8482
I'd like to propose breaking beforeNavigate up into two methods: beforeUnload and beforeNavigate. This would help simplify the documentation and make it explicit in how to deal with the different behaviours.
Describe the proposed solution
Here's what the documentation could look like (and thus, influence the logic)
beforeUnload
A navigation interceptor that triggers before SvelteKit unloads. Calling navigation.confirm() will trigger the native browser unload confirmation dialog.
beforeUnload must be called during a component initialization. It remains active as long as the component is mounted.
beforeUnload((navigation: BeforeUnload) => {
navigation.confirm();
});beforeNavigate
A navigation interceptor that triggers when navigating to a new URL handled by SvelteKit. Navigation can be resolved or rejected, allowing you to prompt the user for confirmation.
beforeNavigate must be called during a component initialization. It remains active as long as the component is mounted.
Basic example using window.confirm
beforeNavigate((navigation: BeforeNavigate) => {
if(window.confirm('Are you sure?')){
navigation.resolve();
} else {
navigation.reject();
}
});Using a custom interface
<script lang="ts">
let attemptedNavigation: BeforeNavigate | undefined;
beforeNavigate((navigation: BeforeNavigate) => {
attemptedNavigation = navigation;
});
const cancel = () => {
attemptedNavigation.reject();
attemptedNavigation = undefined;
}
const confirm = () => {
attemptedNavigation.resolve();
attemptedNavigation = undefined;
}
</script>
{#if attemptedNavigation}
<div>
<p>Are you sure?</p>
<p>
<button on:click={cancel}>Cancel</button>
<button on:click={confirm}>Confirm</button>
</p>
</div>
{/if}Alternatives considered
No response
Importance
would make my life easier
Additional Information
I've purposefully chosen different methods than navigation.cancel() so that we can be clear in the change of behaviour.