Sapper: Svelte transition impacts navigation

Created on 21 Jul 2019  路  14Comments  路  Source: sveltejs/sapper

Describe the bug
If a component used in a route has a transition applied, it will delay navigation and potentially create UI errors.

To Reproduce
In a brand new sapper-template installation, create a new component e.g. Linker.svelte and include it in the index route.

<!-- src/components/Linker.svelte -->
<script>
  import { fade } from "svelte/transition";
  let showImage = false;
</script>

<div
  on:mouseenter={() => {
    showImage = true;
  }}
  on:mouseleave={() => {
    showImage = false;
  }}>

  <h1>Wow hi!</h1>
  <a href="/about">About</a>
  {#if showImage}
    <img
      transition:fade={{ duration: 2000 }}
      src="https://picsum.photos/20"
      alt="" />
  {/if}
</div>
<!-- src/routes/index.svelte -->
<script>
  import Linker from "../components/Linker.svelte";
</script>

...

<Linker />
<h1>Great success!</h1>

Moving the cursor on top of the link, a small picture will slowly fade in. Once clicking on the link, the image will slowly fade out again, but the /about page content will already be appended to the <slot /> and visible in the bottom. If the user moves the cursor back on top of the link while it is fading out, it will just fade in again and prevent the component from being removed completely - causing UI errors.

ezgif-4-99f035a10dee

Expected behavior
When navigating, default behaviour should be to just switch route. No delays nor attempts to finalise transitions or to show both routes in the <slot /> at the same time.

Information about your Sapper Installation:

  • Issue appears in both Chrome and Safari from what I have tested, but I expect this to be the same across all browsers.
  • Using iMac 2011 with OSX Mojave

  • Running in localhost

  • Current latest release v0.27.4

  • Svelte v3

  • dynamic application

  • Using Rollup

Severity
Mainly it is just annoying, and I can't really find a workaround to prevent it unless I just remove the transition from the image having it appear and disappear instantly.

Additional context
Maybe a modifier to the transition could be an idea. We currently have modifiers like once or preventDefault on click events. Maybe add a transition:fade|ignoreRoute={{duration: 200}} or the quite opposite - having the developer purposely asking for route specific transition.

bug routing

Most helpful comment

Does |local not fix this?

https://svelte.dev/docs#Transition_events

All 14 comments

I second this! Right now I have to avoid using transitions to keep navigation working.

Ran into this earlier and only just figured out what it was!

Definitely needs to be fixed.

@thgh I think the specific answer to this problem is to actually not render transitions at all on route change. I don't need items in my list, for example, to fade out when I change the page - I just want them gone.

Does |local not fix this?

https://svelte.dev/docs#Transition_events

Since this issue is still open, I can confirm that |local does fix this problem in my playground.

@romland @mustafa0x for me, |local fixed the issue - so thank you hugely for that.

I think there is an issue with Sapper's routing and the tolerance of transitions, so I will be looking to see if there is a way to fix this when I have time (and brainpower).

Just wanted to +1 this issue. Routing started acting funny as I was writing a back-end api. So I spent 2 hours trying to debug my async calls before finding this.

|local stops components from sticking on navigation, but the animations glitch out. Oh well.

After being stuck for the last few days on what the heck was going on, i found this thread and applied |local to all transitions and finally seems to have fixed my incorrectly destroyed pages.

Be great to get this fixed at some point, ive run into it before too!

@matt3224 are you using an old version of Sapper or Svelte? I'm fairly sure was fixed a few months ago now.

Im using svelte 3.23.2 and 0.27.16 @antony i also thought this had been resolved. If i get time ill see if i can make a repro repo of it

Still seeing this today with latest latest versions. I do my best to now use |local on everything unless that gives undesirable results i then use css transitions and class changes to get around it for now. Would be great to see this fixed once and for all!

On a related note, I feel there's a good argument for making |local the default for transitions.

i do not know if this is the right place, but i have a similar error. I have a List Component with Child Elements like this:

html <IntersectionObserver let:intersecting> {#if intersecting} ... {#if $isMobileOnly} .... {:else} <List horizontal> <div transition:page|local><Card href="/service" title="Service" /></div> <div transition:page|local><Card href="/gallery" title="Gallery" /></div> <div transition:page|local><Card href="/about" title="About" /></div> {/if} {/if} </IntersectionObserver>
When i add |local to my transitions, nothing happend. When i remove |local all Card transitions are fired, when i switch to another page, instead of just executing the transition from the Card i clicked. I also tried to replace my <Card /> with svelte:component this={Card} /> but it doesn't work too.

Is there any other way to fix this? Any ideas?

HA! After three days of trying to find out what the heck is going on I came across this thread and guess what... exact same issue as the OP and applying |local to my transitions fixed things...

A component from routeA showed up on routeB after using a href to go from routeA to routeB so all contents/components of routeB came in below the component from routeA 馃く

Of course I have a ton of <slots> in my code on those two routes, then there's a _layout.svelte in a subdir, the one which routeB is in, and for the first time in my Svelte career I decided using a [slug].svelte route would be a good idea...

That was four days ago... after peeling away one of those layers per day, trying to make sure it's not that thing, I'm here now, four layers deep into the rabbithole 馃ぃ

The fifth layer of course was the browser cache, which I also made sure isn't the problem, that one was Endgegner on level ahm layer 2, which only took about 3 hours to defeat entirely and make sure no stone is left unturned...

Well, |local ftw now it is 馃

For reference, all my package version below... it's up to date code so the issue still seems to be present these days:

sa@m1-mini: ~/0/edm  |master U:2 鉁梶 alias gr | gr svelte package.json
package.json:17:    "@egjs/svelte-infinitegrid": "^3.0.4",
package.json:30:    "@tsconfig/svelte": "^1.0.10",
package.json:52:    "eslint-plugin-svelte3": "^2.7.3",
package.json:79:    "rollup-plugin-svelte": "^7.0.0",
package.json:85:    "svelte": "^3.30.0",
package.json:86:    "svelte-check": "^1.1.17",
package.json:87:    "svelte-click-outside": "^1.0.0",
package.json:88:    "svelte-favicon-badge": "^1.0.0",
package.json:89:    "svelte-forms-lib": "^1.2.2",
package.json:90:    "svelte-grid": "^3.3.1",
package.json:91:    "svelte-inline-input": "^1.2.1",
package.json:92:    "svelte-preprocess": "^4.6.1",
package.json:93:    "svelte-scrollto": "^0.2.0",
package.json:94:    "svelte-spinner": "^2.0.2",
package.json:95:    "svelte-typewriter": "^2.4.1",
package.json:135:   "validate": "svelte-check"
sa@m1-mini: ~/0/edm  |master U:2 鉁梶 gr \"sapper\" package.json
package.json:84:    "sapper": "^0.28.10",
sa@m1-mini: ~/0/edm  |master U:2 鉁梶

Found what was sending me in circles for the last few days... My <PageTransition> component used to create smoother page transitions when changing routes

// PageTransition.svelte

<script>
  import { cubicInOut } from 'svelte/easing'

    let duration = 250
    let delay = duration


    const transitionIn = () => ({
        duration,
        delay,
        easing: cubicInOut,
        css: (t) => `opacity: ${t}`,
    })


    const transitionOut = () => ({
        duration,
        delay: 0,
        easing: cubicInOut,
        css: (t) => `opacity: ${t}`,
    })
</script>


<div in:transitionIn out:transitionOut|local>
    <slot></slot>
</div>

Adding |local to out:transtionsOut fixed all the weirdness I had seen and couldn't easily find for the last few days.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

freedmand picture freedmand  路  4Comments

Snugug picture Snugug  路  4Comments

Rich-Harris picture Rich-Harris  路  3Comments

mylastore picture mylastore  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments