How to make Page Transition using Framer Motion on NextJS
As frontend developers, it is our job to give our website visitors a beautiful User Interface and Experience. The thing about that is more complex because there are a lot of aspects in design. Transition is one aspect we rarely see on the website, but now we can do that with the current technology. So our website will be smoother and easier to navigate into other pages.
Prerequisites
To follow this tutorial, you must have the following tool installed on your computer:
- Node.js 14 or higher | Link
- NPM or Yarn as your Package Manager (I'm using Yarn)
Set up the project
In this page transition tutorial, we are going to use Next.JS 13. If you already have a NextJS project, you can ignore this step, but if you don't have NextJS, you can install it by running this command into your terminal:
npx create-next-app@latest
# or
yarn create next-app
Or, if you want to use typescript, you can run this command instead (note: I'm using typescript):
npx create-next-app@latest --typescript
# or
yarn create next-app --typescript
After we install NextJS, we need to install Framer Motion for our transition library. Before we install it, we need to change the directory into our NextJS, using this command:
cd [your-project-name]
If we are already inside the NextJS project directory, we need to install Framer Motion by running this command:
npm install framer-motion
# or
yarn add framer-motion
After installing successfully, you can test the project by running npm run dev or yarn dev. If installed correctly, you should see this interface in your localhost:3000.
Note: the UI can be different depending on what version your installed NextJS.
Creating Transition Animation
Before we jump into customizing our NextJS components, we must create an animation for our transition. First, we can make a new folder called "components" then we create a file inside it named "transition.jsx" or "transition.tsx", depending on your language. Then your NextJS structure should be like this:
├── .next
├── components --> we create this
│ └── transition.tsx --> our file
├── node_modules
├── pages
│ ├── api
│ ├── _app.tsx
│ ├── _document.tsx
│ └── index.tsx
├── public
├── styles
After creating a new file, we should create an animation using clip-path CSS. The clip-path property allows you to make complex shapes in CSS by clipping an element to a basic shape (circle, ellipse, polygon, or inset) or an SVG source. Feel free to use the Clip-path generator on Google to make your animation, e.g., Clippy. In this tutorial, I will make a wave transition from left to right. So here is the code:
export const wrapperVariants = {
initialState: {
clipPath: 'polygon(0 0, 0 0, 0 100%, 0% 100%)',
transition: { duration: 0.5 },
},
animateState: {
clipPath: 'polygon(0 0, 100% 0, 100% 100%, 0 100%)',
transition: { duration: 0.7, staggerChildren: 0.2 },
},
exitState: {
clipPath: 'polygon(100% 0, 100% 0, 100% 100%, 100% 100%)',
transition: { duration: 0.5 },
},
}
So inside our wrapper, we need to have three objects, each of which has its function in animating our transition:
- initialState is the initial shape before the animation begins.
- animateState is the last shape when the animation ended.
- exitState is the last shape after animateState when we exit the current page.
Customizing NextJS Components
After we create the transition, we will go to _app.tsx files and customize a part of the flow. We need to import some components from Framer Motion, then remember to import the transition that we already made before. More or less you can follow this code below:
import "../styles/globals.css";
import { motion, AnimatePresence } from "framer-motion";
import type { AppProps } from "next/app";
import { useRouter } from "next/router";
import { wrapperVariants } from "../components/transition";
export default function MyApp({ Component, pageProps }: AppProps) {
const router = useRouter();
return (
<>
<AnimatePresence mode="wait" onExitComplete={() => window.scrollTo(0, 0)}>
<motion.div
key={router.route}
initial="initialState"
animate="animateState"
exit="exitState"
transition={{
duration: 0.5,
}}
variants={wrapperVariants}
>
<Component {...pageProps} />
</motion.div>
</AnimatePresence>
</>
);
}
And that's it; we finish our transition animation tutorial. You can test the transition by creating a new page by adding a new file inside the pages folder. Then voilà, you should see a beautiful transition running through your monitor.
Note: It is better to use a
Linkfromnext/linkto navigate to other pages, instead of using an anchor tag.
Published on January 12, 2023