Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Framer Motion Animate Presence is not working with new NextJS App Router's Intercepting Routes

I'm trying to create a modal using intercepting routes as shown in this example on NextJS docs. I'm using framer motion to implement modal animation but Animate Presence is not working in this case.

My page.tsx file inside app/(features)/@loginModal/(.)login/page.tsx

import Modal from "@General/Modal";
import Login from "@Auth/Login";

export default function NavbarLogin() {
    return (
        <Modal>
            <Login />
        </Modal>
    );
}

My layout.tsx file inside app/(features)/layout.tsx

"use client";

import { AnimatePresence } from "framer-motion";
import Navbar from "@Navbar/Navbar";
import Guard from "@Auth/Guard";

export default function MainLayout({
    children,
    loginModal,
}: {
    children: React.ReactNode;
    loginModal: React.ReactNode;
}) {
    console.log(loginModal);
    return (
        <Guard>
            <main>
                <Navbar />
                <div className="pt-20">
                    {children}
                    <AnimatePresence>{loginModal}</AnimatePresence>
                </div>
            </main>
        </Guard>
    );
}

I tried changing the AnimatePresence tag to different locations like the app/layout.tsx, app/(auth)/layout.tsx, app/(auth)/login/page.tsx etc.. in my code but it didn't work.

EDIT: Found this issue on github https://github.com/framer/motion/issues/1850 https://github.com/vercel/next.js/issues/49279 but none of the workarounds mentioned in this is working in the current version. Does anyone know how to fix this in latest version?

like image 891
Kartik Avatar asked Dec 05 '25 23:12

Kartik


1 Answers

When using Animate Presence, the framer components are required to have the entry, exit, and key props.

<AnimatePresence>
                {open && (
                    <motion.div
                        key='box'
                        initial={{ opacity: 0, y: '-100%' }}
                        exit={{ opacity: 0, y: '-100%' }}
                        animate={{ opacity: 1, y: 0 }}
                        transition={{ duration: 0.5, ease: 'easeOut' }}
                        className='flex flex-col items-center justify-center gap-8 md:hidden bg-primary'
                    >
                        ...component related work here
                    </motion.div>
                )}
            </AnimatePresence>

The key prop is important because it's needed by Framer to identify which component to add the animations to.

like image 128
kunalkeshan Avatar answered Dec 07 '25 17:12

kunalkeshan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!