-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
Environment
- Operating System:
Darwin
- Node Version:
v18.20.7
- Nuxt Version:
3.17.4
- CLI Version:
3.25.1
- Nitro Version:
2.11.12
- Package Manager:
npm@10.8.2
- Builder:
-
- User Config:
app
,compatibilityDate
,devtools
,site
,css
,ssr
,modules
,ogImage
,seoExperiments
,linkChecker
,fonts
,image
,vite
- Runtime Modules:
@nuxt/image@1.10.0
,@nuxtjs/seo@3.0.3
,@nuxt/fonts@0.11.2
,lenis/nuxt@1.3.3
- Build Modules:
-
Reproduction
Follow the documentation to apply page transitions: https://nuxt.com/docs/getting-started/transitions
Add this to your nuxt.config.ts file:
export default defineNuxtConfig({
app: {
pageTransition: { name: 'page', mode: 'out-in' }
},
})
As well as this to your app.vue:
<template>
<NuxtPage />
</template>
<style>
.page-enter-active,
.page-leave-active {
transition: all 0.4s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
filter: blur(1rem);
}
</style>
When you switch between pages and you have already scrolled a bit to the bottom you will see the jump between the pages.
Thanks to @awfulcode there is already a minimal reproduction for the issue: https://codesandbox.io/p/devbox/festive-cohen-jg4w3d
Describe the bug
As already mentioned by @awfulcode and others in the Issue #32053 there is a weird bug when using page transitions according to the documentation. There is a problem that the scroll to function is being executed before the page transition finished, results in a jiggy looking page transition since you see the scroll position applied before transition is completed.
I'm currently using a workaround to get around this, but this is not perfect since there is a defined timeout. It would be better if this is properly aligned to the end of the page transition.
I use a app/router.options.ts file to modify the basic scroll behaviour:
import type { RouterConfig } from "@nuxt/schema";
export default <RouterConfig>{
scrollBehavior(to, from, savedPosition) {
if(savedPosition)
{
if(to.path == from.path)
return savedPosition
else
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(savedPosition)
}, 450)
})
}
else{
if (to.hash && to.path == from.path) {
return { el: to.hash }
}
else if(to.hash && to.path != from.path) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ el: to.hash })
}, 450)
})
}
else{
if(to)
{
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ top:0, left:0 })
}, 450)
})
}
else
{
return { top: 0, left: 0 }
}
}
}
}
};
Additional context
No response