HomeBlogsProjectsBookmarksPoemsImagesAboutFeedbackAdmin

Page transition with Framer Motion in Next.js Server Components

Easy page view transitions made with framer motion in Next.js server components. This blog thoroughly covers how to make a smooth view page transition.

04th May, 2024
10 min read
NextJs
JavaScript
Page transition with Framer Motion in Next.js Server Components

Before diving in, let me show you what we’re are going to build today 🔥

framer-ezgif.com-optimize.gif

Smooth right? Let’s build it.

1. Setup

The page.tsx file exports a server component by default. If you have tried working with framer motion before, you’ll probably be familiar with the following error:

Screenshot_2024-05-04_at_8.03.43_PM.png

This is because framer-motion uses functionality that supports only in a client component. The solution is very simple. We make a client component where we import motion tags and the animation presence, and pass everything else as a children.

1.1 The ClientAnimatePresence Component

Make a client-animate-presence.tsx file inside your components folder with the following code:

// src/components/client-animate-presence.tsx

'use client';
import { AnimatePresence, AnimatePresenceProps } from 'framer-motion';

interface ClientAnimatePresenceProps extends AnimatePresenceProps {
  children: React.ReactNode;
}

export default function ClientAnimatePresence(
  props: ClientAnimatePresenceProps,
) {
  return <AnimatePresence {...props}>{props.children}</AnimatePresence>;
}

Now instead of the AnimatePresence component we will use our custom client animate presence component.

1.2 The ClientMotionDiv Component

Similarly, make a client-motion-div.tsx file inside your components folder with the following code:

// src/components/client-motion-div.tsx

'use client';

import { motion, MotionProps } from 'framer-motion';

interface Props extends MotionProps {
  children: React.ReactNode;
}

export default function ClientMotionDiv(props: Props) {
  return <motion.div {...props}>{props.children}</motion.div>;
}

1.3 The PageAnimation component

// src/components/page-animation.tsx


import ClientAnimatePresence from './client-animate-presence';
import ClientMotionDiv from './client-motion-div';

const animation = {
  transition: { duration: 0.2 },
  initial: { opacity: 0, y: 20 },
  animate: { opacity: 1, y: 0 },
  exit: { opacity: 0, y: -20 },
};

export default function PageAnimation({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <ClientAnimatePresence>
      <ClientMotionDiv {...animation}>{children}</ClientMotionDiv>
    </ClientAnimatePresence>
  );
}

That’s it with the setup. It’s time to use animation to your pages.

2. Using the PageAnimation Component

The PageAnimation component now can be used in any server components inside the Nex.tjs (13 | 14) app folder. Here’s an example:

// src/app/poems/page.tsx

import PageAnimation from '@/components/page-animation';

export const metadata = {
  title: 'Poems — Lines that I read and loved',
  description: 'This is the poems page',
};

export default async function Poems() {
  return (
    <PageAnimation>
      <div className='h-screen w-screen p-8 text-lg bg-blue-100 rounded-md'>Hello from my poems page!</div>
    </PageAnimation>
  );
}

And that’s it! Hope you’ve enjoyed reading the post ^^.

If it helped you, help others by sharing the article!

You can also check the implementation on my own portfolio in this github repo.