Skip to content

Proposal: Break beforeNavigate into beforeUnload and beforeNavigate #8625

@oodavid

Description

@oodavid

Describe the problem

I've been thinking a lot about the beforeNavigate interface, as you can see by my recent issues:

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions