motion: Can't get shared layout animations to work with Next.js 13
1. Read the FAQs š
2. Describe the bug
With Next 13, using separation between server and client components, shared layout animations donāt work when implementing the seemingly trivial navigation menu underline. Using either the deprecated or the modern approach (ie. layoutId on the target components).
3. IMPORTANT: Provide a CodeSandbox reproduction of the bug
This issue could be heavily dependent upon styles and nesting(s). The structure honors HTML and React semantics, but it runs complex animations. Hence: the repro is complete, interactive, commentable and with full source code.
Live: https://portfolio-2023-git-feature-implement-layout-maurocolella.vercel.app/
Implementation: https://github.com/maurocolella/portfolio_2023/pull/2/files#diff-f7c999b982bfdbf5f3790e5b148e2343ffb7611b9ba579756dabab9fc76cb2e7
4. Steps to reproduce
On the example page: https://portfolio-2023-git-feature-implement-layout-maurocolella.vercel.app/
Simply click navigation items. Transition doesnāt take place.
5. Expected behavior
I would expect a smooth transition to occur as in the examples.
6. Video or screenshots
N/A.
7. Environment details
Ubuntu Linux 20.04, Chrome beta, Chrome stable, Firefox.
FAQs
Framer Motion wonāt install
Framer Motion 7+ uses React 18 as a minimum. If you canāt upgrade React, install the latest version of Framer Motion 6.
height: "auto" is jumping
Animating to/from auto requires measuring the DOM. Thereās no perfect way to do this and if you have also applied padding to the same element, these measurements might be wrong.
The recommended solution is to move padding to a child element. See this issue for the full discussion.
Type error with AnimateSharedLayout
AnimateSharedLayout was deprecated in 5.0. Refer to the upgrade guide for instructions on how to remove.
Preact isnāt working
Framer Motion isnāt compatible with Preact.
AnimatePresence isnāt working
Have all of its immediate children got a unique key prop that remains the same for that component every render?
// Bad: The index could be given to a different component if the order of items changes
<AnimatePresence>
{items.map((item, index) => <Component key={index} />)}
</AnimatePresence>
// Good: The item ID is unique to each component
<AnimatePresence>
{items.map((item, index) => <Component key={item.id} />)}
</AnimatePresence>
Is the AnimatePresence correctly outside of the controlling conditional? AnimatePresence must be rendered whenever you expect an exit animation to run - it canāt do so if itās unmounted!
// Bad: AnimatePresence is unmounted - exit animations won't run
{isVisible && (
<AnimatePresence>
<Component />
</AnimatePresence>
)}
// Good: Only the children are unmounted - exit animations will run
<AnimatePresence>
{isVisible && <Component />}
</AnimatePresence>
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 30
- Comments: 88
Commits related to this issue
- Swap entire Next.js folder structure from App to Pages, fixes route transitions For more info, see: https://github.com/framer/motion/issues/1850 — committed to wolfpilot/wolfpilot.github.io by wolfpilot a year ago
- Refactor entire Next.js folder structure from App to Pages, fixes page transition bug For more info, see: https://github.com/framer/motion/issues/1850 — committed to wolfpilot/wolfpilot.github.io by wolfpilot a year ago
- Add component to fix `framer-motion` work properly - For More details, check [here](https://github.com/framer/motion/issues/1850#issuecomment-1445239322) — committed to iputapp/lounas by wiyco a year ago
- Add component to fix `framer-motion` work properly (#12) - For More details, check [here](https://github.com/framer/motion/issues/1850#issuecomment-1445239322) — committed to iputapp/lounas by wiyco a year ago
- added Frozen router for framer motion exit animations to work — committed to Gaurav4604/React-Showcase by Gaurav4604 9 months ago
I was using old architecture of pages in Next-13.4. This article helped me solved it: https://blog.logrocket.com/advanced-page-transitions-next-js-framer-motion/#adding-animatepresence
The issue was adding key={router.pathname} in the _app.tsx and it worked.
Hereās my experimental branch of next.js that enables exit transitions with
AnimatePresenceby adding in a customGluecomponent (supplied in aglue.tsx) where we can monitor the lifecycle of routes:Draft PR: https://github.com/vercel/next.js/pull/56591 Discussion: https://github.com/vercel/next.js/discussions/56594
The final solution in
next.jsis going to have to inevitably be something of this sort, as this enables route transitions even within parallel routes (where you canāt rely onpathnameor global navigation events to perform the transitions).Closing here as framework-specific integrations isnāt something Iām going to concentrate on this year.
I got exit animation to work using
appDir(13.2.2-canary1).template.tsxis a lie, so ignore that until they fix it. What you want to do is in yourlayout.tsx(which is ideallyrsc), wrap aClientcomponent around your{children}and have that be wrapped in the<AnimatePresence>component.It turned out to start the animation of entry and exit. Maybe someone will be useful š
https://github.com/AksRK/next13-page-transition
Wow, four months in and still not a fix. Next.js devs are sleeping.
Ive made some progress on this. I still cannot get exit animations to work, but this snippet works well for enter animations that are pretty smooth. The only problem is that these dont load when the server is initial SSRing the page. after its cached it works fine. In the video, the documents page SSRās on the first click, then after that you get decently smooth transitions.
https://github.com/framer/motion/assets/34988548/f18dec5d-ec75-40f5-8738-892349efb3a2
@SchmidtDavid I am sorry I didnāt follow up with Next.js/Vercel in part because the app directory was in rapid flux/beta at that time. There were several known instabilities and incompatibilities with the wider React ecosystem.
I was hoping that the framer motion team (@mattgperry ) would have more direct channels & bandwidth to look into it.
That said, given the traction this has gained, and that the app directory is emerging/has emerged from beta, I am more than happy to follow up.
Here. I have filed a bug with Next.js.
In the meantime, for some of these scenarios, a possible workaround is to simply use CSS transitions, or the gorgeous view transitions now available in Chrome.
Your example uses the
pagesdirectory. @maurocolella uses the new/appdirectory: https://beta.nextjs.org/docs. While still experimental itās definitely the new way of creating Next apps.There are seemingly a couple of issues with transitions. Most notable: the exit animations do not work (see video). Iām not sure whether the issue is with Framer or with Next. Next does seem to unmount the layout immediately upon navigation. Iāve tried adding
usePresenceto allow Framer to remove an element after a timeout but even that doesnāt work.The props on the component doing the transition are:
https://user-images.githubusercontent.com/6362631/213143210-634ce3fc-49ad-4135-b92a-9b1fe8aaa88d.mov
still doesnāt work
@alainkaiser itās seeming like this is an issue on the Next.js side that will need to be fixed: https://github.com/vercel/next.js/issues/49279
Yes, I will put it on my list. I will link the bug here.
@khuezy in my instance
pathnamefalls into an infinite loop and no route change happensHey folks, Iām running into the same issue here. Iām not sure how to even wrap
AnimatePresencein NextJsās new App directory because itās throwing all kinds of issues. Iām combining it withstyled-componentsand seems like thereās some stuff thatās happening there too.Hereās how Iāve currently implemented my
layout.js:One of the biggest errors Iām getting is:
Thank you @Frumba and @Gaurav4604 ā that worked, thank you for the quick reply.
Hi everyone, I followed this thread and came across a hacky solution, It seems to work well for me
Check it out, might be useful.
using
The thread itself has a working example, but Iāve implemented a solution with much less code as well.
My working example (it is a frontendmentor.io challenge solution)
Repo link
This is the FrozenRouter implementation that makes exit animations possible
Here is where the FrozenRouter component is being used
I hope this is helpful to all facing this issue.
Having the same problem with the new app directory, a thing I noticed is that itās exclusively the exit animation bc I also have the āinitialā prop set to false in AnimatePresence and that works hahaha
`export default function RootLayout({children }) { return (
) }`
Not sure if itās a Framer motion or Next issue at this point though š
It does work but you have to be a bit creative with it. Hereās my solution.
I have the same kind of issue in the Next 13. The Animate Presence is unable to freeze the exiting (children) component.
In the Root Layout, which is a server component, I have this:
In Main (client component) I have this:
In Inner (client component as well):
I added Freeze(react-freeze) as a workaround, but I donāt like it.
It seems that both (the new component + the existing one) point somehow to the same component.
@baptistebriel Check the new version of the Child with the forwardRef here https://github.com/npostulart/nextgram-with-page-transitions/blob/main/src/app/ClientLayout.tsx#L12 š
I can second this š
That being said I was able to get it working without an exit animation by using the motion tag as the root tag on each page (i.e., home, about, contact) and not using mode=āwaitā with AnimatePresence.
It looks like appDir is stable as of 13.4 today. Looking forward to getting a fix on this soon
I also give a try on the new app folder and indeed I have trouble with the exit animation, it just donāt work in the new App even with the template.js and separate it as a client component, however, in the pages folder it works fine.
@dumbravaandrei22 Iām using 9.0.3, Iāll update to latest and let you know. Although the example above gets exit animations to work, the current problem is that nextjs replaces the contents before the exit animation plays. I believe once
Vercelfixestemplate.tsx, it will behave correctly. Edit: 10.0.1 exit animations work, but the premature navigation is still a problem. Lee from Vercel is aware of it so maybe itās on their plate.@mattgperry was private, sorry.
Here is the sandbox:
https://codesandbox.io/s/hopeful-wozniak-hkf8yx
@cdebotton I just updated my import for frozenRouter for it to work with AnimatePresence on nextJS 13.5.1, You can find it here but I get it, this needs a much more permanent fix, since these are not publicly exported components from nextJS.
Just a follow up, Iām trying this approach in Next 13.5 which just came out today and Iām finding that any components underneath the Frozen Router Component wonāt update via HMR which makes it pretty much unusable.
This is a direct issue with next, and not framer. Once this issue is resolved it should work as indeed.
+1 same problem, would love to see a fix for exit animations, tried on latest Next canary release (13.3.2-canary.6) and still not working
I havenāt found a related ticket on the nextjs repo. Maybe we can create w/ some a minimal repro?
Ah I see, sorry missed your comment up there. We have the exact same problem.
I have it working for like 90%. The animation on Exit is or too fast loading animate-in or the exit is is too fast or too slow. The exit and enter works⦠but still works better using āpagesā instead of the new āappā directory.
layout.tsx:
Another finding: When using
<AnimatePresence>in template.tsx, theonExitComplete()does not fire.After reading the Next.js v13 docs regarding the new Templates feature, I tried it out to house page-transition Framer Motion code.
Unfortunately the exit animation does not work (itās just completely ignored).
This is the file that contains my page-transition code.
Also see my template.tsx and layout.tsx file for more context.
Per https://github.com/framer/motion/discussions/1775#discussioncomment-4299578 I have also tried using a
template.tsxfile but that doesnāt seem to work either, even though the Next docs specifically mention transitions to be a use-case for it: https://beta.nextjs.org/docs/routing/pages-and-layouts#templates.Hi there, that source code link isnāt working for me. Please reopen with a sandbox or repo