DEV Community

Cover image for How to add page transitions to a nextjs app
Navicstein Rotciv
Navicstein Rotciv

Posted on

10 3

How to add page transitions to a nextjs app

This tutorial assumes that you're already familiar with next.js and just what to add transitions to your pages and that you're have hope of using typescript

Step 1

Install required dependency

$ npm install react-transition-group
Enter fullscreen mode Exit fullscreen mode

if you're using Typescript install the types for it

$ npm install -D @types/react-transition-group
Enter fullscreen mode Exit fullscreen mode

Step 2

create a Transition.tsx component in the component folder

import {
  TransitionGroup,
  Transition as ReactTransition,
} from "react-transition-group"

import { ReactChild } from "react"

type TransitionKind<RC> = {
  children: RC
  location: string
}

const TIMEOUT: number = 200

const getTransitionStyles = {
  entering: {
    position: `absolute`,
    opacity: 0,
    transform: `translateX(50px)`,
  },
  entered: {
    transition: `opacity ${TIMEOUT}ms ease-in-out, transform ${TIMEOUT}ms ease-in-out`,
    opacity: 1,
    transform: `translateX(0px)`,
    animation: "blink .3s linear 2",
  },
  exiting: {
    transition: `opacity ${TIMEOUT}ms ease-in-out, transform ${TIMEOUT}ms ease-in-out`,
    opacity: 0,
    transform: `translateX(-50px)`,
  },
}

const Transition: React.FC<TransitionKind<ReactChild>> = ({
  children,
  location,
}) => {
  return (
    <TransitionGroup style={{ position: "relative" }}>
      <ReactTransition
        key={location}
        timeout={{
          enter: TIMEOUT,
          exit: TIMEOUT,
        }}
      >
        {(status) => (
          <div
            style={{
              ...getTransitionStyles[status],
            }}
          >
            {children}
          </div>
        )}
      </ReactTransition>
    </TransitionGroup>
  )
}
export default Transition
Enter fullscreen mode Exit fullscreen mode

Step 3

Next, import this Transition.tsx component to your layouts/MainLayout or _app.tsx if you're doing this in the _app.tsx be sure to replace children with <Component {...pageProps} />.

We have imported useRouter from next//router and passed the pathname to location props

// import this `Transition.tsx` component to your `layouts/MainLayout` or `_app.tsx`
import React, { Fragment } from "react"
import Transition from "../components/Transition"
import { useRouter } from "next/router"

const MainLaylout: React.FC = () => {
  const router = useRouter()

  return (
    // you may import your header and footer here too
    <Fragment>
      <Transition location={router.pathname}>
        <div className="min-h-screen">{children}</div>
      </Transition>
    </Fragment>
  )
}
// React.memo may not be important
export default React.memo(MainLaylout)
Enter fullscreen mode Exit fullscreen mode

Step 4

Now you have everything ready it's time to use the MainLayout in our pages..
to use the layout, import and wrap your pages with MainLayout

for example

import React, { Fragment } from "react"
// path to your main layout
import MainLayout from "layouts/MainLayout"

const IndexPage: React.FC = (props) => {
  return (
    <MainLayout>
      <div> replace with your content here..</div>
    </MainLayout>
  )
}
export default React.memo(IndexPage)
Enter fullscreen mode Exit fullscreen mode

Wrap each of your pages with the main layout, congratulations, you've just added page transitions to a nextjs app

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (4)

Collapse
 
larsejaas profile image
Lars Ejaas

This is really cool. I need to dig a bit into this, as I do not get any page-transitions between pages when transitioning between pages build on the same page-file but on different routes. But this is a really solid starting point and a lot lighter on bundle size compared to something like Framer. Thanks for the article - it really helped a lot!

Collapse
 
larsejaas profile image
Lars Ejaas

Small follow up if anyone is facing a similar issue:

router.pathname is the path to the page-file. So when you pass routher.pathname as a prop to the Transition component you will only get a transition when you navigate to a page that is based on another page-file. This will probably work fine in most instances, but if you use a CMS for content (my current project uses headless WordPress) you could be using the same file ( e.g. page/[...page].tsx ) to generate a lot of different pages.
The workaround is to pass router.asPath instead. This way you will get a transition every time the page is navigated to a different url.

Collapse
 
hocoh profile image
Hocoh • Edited

Awesome bro, you saved my day !
it works fine now,
looking forward for your next tutorials.

Collapse
 
arionarian profile image
Rian Ariona

Not working if the page has serverSideProps 🤷‍♂️ Any idea to make this work?

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay