Open Tal500 opened 1 year ago
I don't think there's anything we can do here. The page
store only updating after the navigations completes is the correct behavior. To do what you want it's probably better to use the $navigating
store to map all changes from null
to <something>
to a key that changes every time that happens.
This sounds like something for an examples or recipes section.
I don't think there's anything we can do here. The
page
store only updating after the navigations completes is the correct behavior. To do what you want it's probably better to use the$navigating
store to map all changes fromnull
to<something>
to a key that changes every time that happens.This sounds like something for an examples or recipes section.
Thanks for the workaround! If it helps, the key I used was ($navigating?.to ?? $page.url).pathname
, but it have the problem that it can animate a page entrance even when the page wasn't fully loaded, resulting the same issue but the oppoisite - now on heavy load, the old page will entrance as well, and suddenly, when the loading finish, the new page will be replaced immediately.
For fixing this potential behavior, you need to do both use key and if blocks with navigation:
{#key $navigating}
{#if !$navigating}
<div in:fly={{ x: -5, duration: 500, delay: 500 }} out:fly={{ x: 5, duration: 500 }}>
<slot />
</div>
{/if}
{/key}
This will make the previous page to always be transitioned out, but the new page will not be transitioned in before the navigation is complete.
Side effect of the solution: if the loading takes X
milliseconds to complete, the transition in in this code will be only after 500 + X
milliseconds because of the delay, when it should have been max(500, X)
instead.
A better solution will be to use the following code instead (where outroFinished
is a variable initialized to true
):
{#if !$navigating && outroFinished}
<div transition:fly={{ x: 5, duration: 500 }} on:outrostart={() => { outroFinished = false; }} on:outroend={() => { outroFinished = true; }} >
<slot />
</div>
{/if}
@Tal500 @dummdidumm
My solution for this was to simply use the afterNavigate()
lifecycle hook:
// +layout.svelte
<script>
import { afterNavigate } from '$app/navigation'
let show_special_links = false
afterNavigate(async (nav) => {
const { from, to } = nav;
show_special_links = to.url.href.includes('/special-address');
});
</script>
<Nav>
{#if show_special_links}
<SpecialNavLinks />
{/if}
</Nav>
@Tal500 @dummdidumm My solution for this was to simply use the
afterNavigate()
lifecycle hook:// +layout.svelte <script> import { afterNavigate } from '$app/navigation' let show_special_links = false afterNavigate(async (nav) => { const { from, to } = nav; show_special_links = to.url.href.includes('/special-address'); }); </script> <Nav> {#if show_special_links} <SpecialNavLinks /> {/if} </Nav>
Notice that this solution may suffer from the side effect I mentioned in my previous comment.
Notice that this solution may suffer from the side effect I mentioned in my previous comment.
Agreed, but for most use-cases, I think it's going to fit the intended effect with more consistent/predictable behavior for your average user.
<script>
import { navigating } from "$app/stores";
</script>
{#key $navigating}
{#if !$navigating}
<main
transition:fly={{
x: window.innerWidth,
duration: 1000,
easing: elasticInOut,
}}
>
<slot />
</main>
{/if}
{/key}
thanks @Tal500, that worked very fine!
Describe the bug
We all like Svelte transitions, and some of us are using them for page transitions. A good repo. example for page transitions is this one, by basically doing something like this code in the main layout:
The repo. I mentioned, is passing the pathname in the
load
function of the layout, so in their code,pathname
equals todata.pathname
. The disatvantage of this method, is that the main layout load function will be invalidated every time the page is changing, which is probably very wasteful.The obvious solution is to use the
page
store instead, and substitute inpathname
the value of$page.url.pathname
instead. However, the transition fails, and it looks like thepage
store is being updated too late, causing the transition to take place after the slot has already been changed, resulting with the effect that the new page is also rendered on the outro transition:https://user-images.githubusercontent.com/1467072/204525557-1fa4658f-3129-4c8f-b665-355c1f420f8b.mp4
Upgrading the
svelte
and the@sveltejs/kit
packages results with the same effect.Reproduction
npm install
andnpm run dev
. You'll see everything works well.<PageTransition pathname={data.pathname}>
to<PageTransition pathname={$page.url.pathname}>
, and of course import thepage
store byimport { page } from '$app/stores';
. You'll see now the same results as in the video above.Logs
No response
System Info
Severity
serious, but I can work around it
Additional Information
No response