-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat] beforeNavigate
and afterNavigate
lifecycle functions
#3293
Conversation
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
beforeNavigate
and afterNavigate
lifecycle functions
Example of a 'you have unsaved changes' modal that works with internal navigations and <script>
import { beforeNavigate, goto } from '$app/navigation';
let intercepted = null;
let unsaved = true;
beforeNavigate(({ to, cancel }) => {
if (!unsaved) return; // nothing to do
if (intercepted) return; // we're here because of the `goto`
cancel();
// if `to` has a value, we're navigating internally and
// should display our own modal. otherwise, we're in
// beforeunload, which means the user will already
// see a system dialog and doesn't need ours too
if (to) {
intercepted = { url: to };
}
});
</script>
{#if intercepted}
<div class="modal-background" on:click={() => (intercepted = null)}>
<div class="modal" on:click={(e) => e.stopPropagation()}>
<p>you have unsaved changes!</p>
<button on:click={() => (intercepted = null)}>stay on page</button>
<button on:click={() => goto(intercepted.url)}>leave page</button>
</div>
</div>
{/if} |
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A late review, but I have a question below 😬
@@ -122,7 +151,7 @@ export class Router { | |||
addEventListener('sveltekit:trigger_prefetch', trigger_prefetch); | |||
|
|||
/** @param {MouseEvent} event */ | |||
addEventListener('click', (event) => { | |||
addEventListener('click', async (event) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove this async
Sorry I'm late to the party.
The only problem with this is if the user navigated backwards with the browser controls. |
Looks like you got it figured out: https://discord.com/channels/457912077277855764/939868205869072444/946323798477656084 |
Hello, I followed the above but am and am able to block the navigation but onbeforeunload is not being called and I don't see the native popup. |
Todo (from discussion below):
beforeNavigate
andafterNavigate
beforeNavigate
callback synchronous{from, to}
) tobeforeNavigate
(andafterNavigate
?)cancel
function tobeforeNavigate
instead of returningfalse
beforeNavigate
should work with external navigation as well as internal navigationbeforeNavigate
should callonbeforeunload
on the user's behalfFor whatever reason, I can't sync my local version of #2982 with that branch, so I've duplicated it for further review. All credit belongs to @zommerberg!
Fixes #2974, fixes #560, and fixes #552.
Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
Tests
pnpm test
and lint the project withpnpm lint
andpnpm check
Changesets
pnpx changeset
and following the prompts. All changesets should bepatch
until SvelteKit 1.0