Framer Motion and Next JS
Answered
Gharial posted this in #help-forum
GharialOP
I'm working on a Next.js project and have encountered an issue when integrating Framer Motion for animations. I'm facing a runtime error that I haven't been able to resolve.
Environment:
Next.js Version: 14.0.2
React Version: 18
Framer Motion Version: 10.16.4
Problem:
Whenever I use the <motion.img> component from Framer Motion in my Next.js application, I get the following runtime error:
Code Snippet:
Here's a snippet of the code where the error occurs:
I'm not using any custom Webpack or Babel configurations that could interfere with module resolution. Also, I've not encountered this issue with other components or libraries in the project.
Any help would be greatly appreciated. I have been banging my head against the wall for a while now...
Environment:
Next.js Version: 14.0.2
React Version: 18
Framer Motion Version: 10.16.4
Problem:
Whenever I use the <motion.img> component from Framer Motion in my Next.js application, I get the following runtime error:
Uncaught Error: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function
This error seems to be related to React's Context API, but I'm unsure why it's occurring given that I'm using a compatible version of React.
Code Snippet:
Here's a snippet of the code where the error occurs:
import Link from 'next/link';
import { motion } from 'framer-motion';
const Navbar = () => {
return (
<nav>
{/* Other nav items */}
<Link href="/">
<motion.img
src="/path/to/image"
alt="Description"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
/>
</Link>
{/* Other nav items */}
</nav>
);
};
export default Navbar;
I'm not using any custom Webpack or Babel configurations that could interfere with module resolution. Also, I've not encountered this issue with other components or libraries in the project.
Any help would be greatly appreciated. I have been banging my head against the wall for a while now...
Answered by Siberian Flycatcher
Hi 👋.
You need to mark the
Two possible ways of doing that:
1. Mark your entire NavBar component with
2. Create a separate client component for your image and mark it with "use client"
app/motion.js
app/navbar.js
You need to mark the
motion
component with "use client"
.Two possible ways of doing that:
1. Mark your entire NavBar component with
"use client"
"use client"
import Link from 'next/link';
import { motion } from 'framer-motion';
const Navbar = () => {
return (
<nav>
{/* Other nav items */}
<Link href="/">
<motion.img
src="/path/to/image"
alt="Description"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
/>
</Link>
{/* Other nav items */}
</nav>
);
};
export default Navbar;
2. Create a separate client component for your image and mark it with "use client"
app/motion.js
"use client";
import { motion } from "framer-motion";
export function MotionImage(props) {
return <motion.img {...props} />;
}
app/navbar.js
import Link from 'next/link';
import MotionImage from './motion';
const Navbar = () => {
return (
<nav>
{/* Other nav items */}
<Link href="/">
<MotionImage
src="/path/to/image"
alt="Description"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
/>
</Link>
{/* Other nav items */}
</nav>
);
};
export default Navbar;
5 Replies
Original message was deleted
Siberian Flycatcher
Hi 👋.
You need to mark the
Two possible ways of doing that:
1. Mark your entire NavBar component with
2. Create a separate client component for your image and mark it with "use client"
app/motion.js
app/navbar.js
You need to mark the
motion
component with "use client"
.Two possible ways of doing that:
1. Mark your entire NavBar component with
"use client"
"use client"
import Link from 'next/link';
import { motion } from 'framer-motion';
const Navbar = () => {
return (
<nav>
{/* Other nav items */}
<Link href="/">
<motion.img
src="/path/to/image"
alt="Description"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
/>
</Link>
{/* Other nav items */}
</nav>
);
};
export default Navbar;
2. Create a separate client component for your image and mark it with "use client"
app/motion.js
"use client";
import { motion } from "framer-motion";
export function MotionImage(props) {
return <motion.img {...props} />;
}
app/navbar.js
import Link from 'next/link';
import MotionImage from './motion';
const Navbar = () => {
return (
<nav>
{/* Other nav items */}
<Link href="/">
<MotionImage
src="/path/to/image"
alt="Description"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
/>
</Link>
{/* Other nav items */}
</nav>
);
};
export default Navbar;
Answer
@Siberian Flycatcher Hi 👋.
You need to mark the `motion` component with `"use client"`.
Two possible ways of doing that:
**1. Mark your entire NavBar component with `"use client" `**
jsx
"use client"
import Link from 'next/link';
import { motion } from 'framer-motion';
const Navbar = () => {
return (
<nav>
{/* Other nav items */}
<Link href="/">
<motion.img
src="/path/to/image"
alt="Description"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
/>
</Link>
{/* Other nav items */}
</nav>
);
};
export default Navbar;
**2. Create a separate client component for your image and mark it with "use client"**
*app/motion.js*
jsx
"use client";
import { motion } from "framer-motion";
export function MotionImage(props) {
return <motion.img {...props} />;
}
*app/navbar.js*
jsx
import Link from 'next/link';
import MotionImage from './motion';
const Navbar = () => {
return (
<nav>
{/* Other nav items */}
<Link href="/">
<MotionImage
src="/path/to/image"
alt="Description"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
/>
</Link>
{/* Other nav items */}
</nav>
);
};
export default Navbar;
GharialOP
Oh, thank you! Is there any documentation for this that I can read? Just for future reference and to make sure that I fully understand it.
I should probably google this before asking. Sorry!
Siberian Flycatcher
Sure, check out this section for when to use Server vs Client component in Next.js https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns
Here is the thread on Framer for adding "use client" directive
https://github.com/framer/motion/issues/2054
Here is the thread on Framer for adding "use client" directive
https://github.com/framer/motion/issues/2054
GharialOP
You're the man. Thank you!