Logo
Published on

Next.js 13 + Framer Motion Page Transitions

Authors

Today we'll have a look at how to add a simple slide-in animation to all our pages using Next.js framework and Framer Motion.

Prerequisite: Setup a Next.js project with Typescript, understand how Framer Motion works

Step 1: Install Framer Motion

Open up your terminal, navigate to your project folder and install Framer Motion using your package manager

npm install framer-motion

Step 2: Create a template file in your app directory

Create a new .tsx file in your app directory called template.

app/template.tsx
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}

Templates are very similar to Layouts in Next.js in a sense that they wrap our pages / routes so whenever you visit a page in Next.js the "closest" template component will be rendered as well.

You can learn more about how templates work in Next.js 13 here but the high-level idea for now is to trigger an animation every time a user navigates to a page/route.

templates create a new instance for each of their children on navigation. This means that when a user navigates between routes that share a template, a new instance of the component is mounted, DOM elements are recreated, state is not preserved, and effects are re-synchronized. --- Next.js docs

Step 3: import Framer Motion and Create Animation

Keep in mind Framer Motion uses part of the React API which is not accessible to server components so you need to add the "use client" directive on top. More on this here.

Then prepare the variants in which between the transition will happen and wrap the template children in a motion component. You can customise these further if you need a different animation or you want to add some extra like an exit animation.

app/template.tsx
"use client"
import { motion } from "framer-motion"

const variants = {
hidden: { opacity: 0, x: -200, y: 0 },
enter: { opacity: 1, x: 0, y: 0 },
}

export default function Template({ children }: { children: React.ReactNode }) {
  return (
    <motion.main
      variants={variants}
      initial="hidden"
      animate="enter"
      transition={{ type: "linear" }}
    >
      {children}
    </motion.main>
  )
}

Step 4: Enjoy

Done. You should see a smooth transition now between pages thanks to the slide-in animation. The driver behind this article was to give you a quick and simple example but I encourage you to take the time to learn more about Framer Motion as there are some amazing and much more advanced options in there that can take your user experience to new levels.