Reputation: 499
I'm studying Next.JS and Framer Motion to improve my skills. So, I'm trying to make a fade-in/fade-out page transition, but can't get it to work properly, and can't figure out why.
The fade-in animation works fine, but, when I click (change current page), the fade-out isn't showing...
Here's my code:
/shared/layout.js
export default function Layout({ children }){
return (
<>
<Head>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
</Head>
<Header />
<main>
<AnimatePresence exitBeforeEnter>
{ children }
</AnimatePresence>
</main>
</>
)
}
/pages/_app.js
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default MyApp
/pages/index.js
export default function Home(){
return (
<motion.div id="home" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: .5 }}>
<Head>
<title>Home</title>
</Head>
// Bla bla bla goes here
</motion.div>
);
}
/pages/about.js
export default function About(){
return (
<motion.div id="about" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: .5 }}>
<Head>
<title>About</title>
</Head>
// Bla bla bla goes here
</motion.div>
);
}
/pages/contact.js
export default function Contact(){
return (
<motion.div id="home" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: .5 }}>
<Head>
<title>Contact</title>
</Head>
// Bla bla bla goes here
</motion.div>
);
}
While searching, I've found a lot of people saying "currently, exit animation won't work if you don't add an initial state", but I'm using initial prop on all motion.div components, and my AnimatePresence is in the right place (I think), as the parent for all motion.div components.
Can someone help me?
Thanks!
Upvotes: 3
Views: 2081
Reputation: 1487
I did almost the same and I had the same issue.
I resolved it by doing this in /pages/_app.js
:
function MyApp({ Component, pageProps, router }) {
return (
<Layout>
<Component key={router.pathname} {...pageProps} />
</Layout>
)
}
export default MyApp
So I just added a key for the Component
using the router given by Nextjs.
Upvotes: 1
Reputation: 2406
I achieved the same by using following code in the _app
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
key={router.asPath}
transition={{
duration: 0.3,
ease: 'easeInOut',
type: 'tween',
}}
>
<Component {...pageProps} />
</motion.div>
Upvotes: 1