Animating Layout Transitions in Next.js 14 with Framer Motion

Example of implementing smooth layout transitions when navigating between pages in a Next.js 14 app using Framer Motion for animation.
import { motion, AnimateSharedLayout } from 'framer-motion';

// Wrap your application with AnimateSharedLayout to enable shared layout animations
function MyApp({ Component, pageProps }) {
  return (
      <Component {...pageProps} />

export default MyApp;
This snippet should be placed in your custom '_app.js' file. It wraps the entire application with the AnimateSharedLayout component from Framer Motion which allows for shared layout animations across the whole app.
import { motion } from 'framer-motion';

export default function PageLayout({ children }) {
  // Define your animation variants
  const variants = {
    hidden: { opacity: 0, x: -100, y: 0 },
    enter: { opacity: 1, x: 0, y: 0 },
    exit: { opacity: 0, x: 100, y: 0 }

  return (
      transition={{ type: 'linear' }}
Create a `PageLayout` component that wraps the content of each page. This component uses the `motion.div` from Framer Motion with predefined animation variants for 'hidden', 'enter', and 'exit' states, as well as a transition property.
import PageLayout from './PageLayout'; // Assume PageLayout is in the same directory

function HomePage() {
  return (
      <h1>Welcome to the homepage</h1>
      {/* Rest of your homepage content */}

export default HomePage;
This snippet shows how to use the `PageLayout` component in a specific page, in this case `HomePage`. The page's content should be wrapped inside `PageLayout` to enable the defined animations during page transitions.
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { motion, useAnimation } from 'framer-motion';

function usePageTransition() {
  const controls = useAnimation();
  const router = useRouter();

  useEffect(() => {
    const handleStart = () => {

    const handleComplete = () => {
    };'routeChangeStart', handleStart);'routeChangeComplete', handleComplete);

    return () => {'routeChangeStart', handleStart);'routeChangeComplete', handleComplete);
  }, [controls,]);

  return controls;
The custom hook `usePageTransition` can be used to control the start of exit and enter animations programmatically using Next.js router events. By calling this hook and passing the returned controls to a `motion` component, you can sync your animations with page transitions.