Advanced Page Transitions with Next.js and Framer Motion

June 8, 2024 - 3 min read - 0 views

In this tutorial, we'll explore how to create advanced page transitions in Next.js using Framer Motion. Framer Motion is a powerful library for animations and gestures that integrates seamlessly with React.

Getting Started

First, ensure that you have Framer Motion installed in your Next.js project. You can install it using npm or yarn:

npm install framer-motion
thumbnail

Once installed, you can start using Framer Motion in your Next.js application.

Basic Setup

We'll begin by setting up a simple page transition. Create a motion component from Framer Motion and use it to wrap your page content.

// pages/_app.tsx
import { useRouter } from "next/router";
import { AnimatePresence, motion } from "framer-motion";
import "../styles/globals.css";
 
function MyApp({ Component, pageProps }) {
  const router = useRouter();
 
  return (
    <AnimatePresence exitBeforeEnter>
      <motion.div
        key={router.route}
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        transition={{ duration: 0.5 }}
      >
        <Component {...pageProps} />
      </motion.div>
    </AnimatePresence>
  );
}
 
export default MyApp;

In this setup, we use AnimatePresence to manage the exit and entry animations for page transitions, and motion.div to define the transition animations.

Advanced Transitions

For more advanced transitions, you can customize the animation properties and add multiple transitions. Here, we'll create a slide transition.

// pages/_app.tsx
import { useRouter } from "next/router";
import { AnimatePresence, motion } from "framer-motion";
import "../styles/globals.css";
 
const variants = {
  initial: { opacity: 0, x: 100 },
  animate: { opacity: 1, x: 0 },
  exit: { opacity: 0, x: -100 },
};
 
function MyApp({ Component, pageProps }) {
  const router = useRouter();
 
  return (
    <AnimatePresence exitBeforeEnter>
      <motion.div
        key={router.route}
        initial="initial"
        animate="animate"
        exit="exit"
        variants={variants}
        transition={{ duration: 0.5 }}
      >
        <Component {...pageProps} />
      </motion.div>
    </AnimatePresence>
  );
}
 
export default MyApp;

In this example, we define a variants object to manage the initial, animate, and exit states of our page transitions, making the page slide in and out horizontally.

Combining Animations

You can also combine multiple animations for a more dynamic experience. For instance, combining opacity and scale transformations.

// pages/_app.tsx
import { useRouter } from "next/router";
import { AnimatePresence, motion } from "framer-motion";
import "../styles/globals.css";
 
const variants = {
  initial: { opacity: 0, scale: 0.8 },
  animate: { opacity: 1, scale: 1 },
  exit: { opacity: 0, scale: 1.2 },
};
 
function MyApp({ Component, pageProps }) {
  const router = useRouter();
 
  return (
    <AnimatePresence exitBeforeEnter>
      <motion.div
        key={router.route}
        initial="initial"
        animate="animate"
        exit="exit"
        variants={variants}
        transition={{ duration: 0.5 }}
      >
        <Component {...pageProps} />
      </motion.div>
    </AnimatePresence>
  );
}
 
export default MyApp;

Here, the page content scales in and out while also adjusting its opacity, creating a more visually engaging transition.

Conclusion

Framer Motion provides a powerful and flexible way to create smooth and dynamic page transitions in Next.js. By mastering these techniques, you can significantly enhance the user experience of your web applications.

Feel free to experiment with different animations and properties to achieve the desired effects. If you have any questions or run into issues, leave a comment below or check out the Framer Motion documentation.