Page Transitions in Gatsby with Framer Motion

Brad Carter
3 min readDec 21, 2020

Framer Motion is a great way to add animation to a React project, and Gatsby Link makes linking between pages a breeze. In this article, I’ll show you how I combined the two to create the page transitions I used on my portfolio site.

Start by installing Framer Motion and importing a motion component to your starting page. For our link component, we’ll be using Gatsby Plugin Transition Link, and will need to import TransitionLink and TransitionState to our starting page as well. Note that TransitionLink is essentially a regular Link component with a few additional options, so you’ll need basic familiarity with Gatsby Link.

Wrap your page in a TransitionState component and pass transitionStatus, entry and exit to your page’s content as shown in the image below. Transition status has 4 possible values: entering, entered, exiting, and exited. We’ll use these values to control the start/stop of our animations. The entry and exit values will control what the animations do. If this starts to get a little confusing, but just know that entry and exit are custom values we’ll create, and everything else is a value from transitionStatus telling us what the page is currently doing.

Wrap your page’s content in this.

Make your top level element a <motion.div> with initial = entry.state. This will be the starting position we set in our TransitionLink going back to this page. The value we’re animating to will be dependent on whether the component is entering or exiting. If it’s exiting the div will animate to exit.state (set in whatever TransitionLink component the user clicks to leave the page), otherwise it will animate to the final static position we’d like our div at. We’ll also set the duration of our transition to be dependent on whether the page is exiting or not so that we can pass in a custom length from the TransitionLink that is clicked. This is what our final div should look like:

Now in each TransitionLink we create, we can set custom values for the animations of our current exiting page (the top level motion.div) and new entering page:

Then we just pass the transitionStatus and entry prop to the page that’s entering:

Make sure to check if your window is undefined or not before using any window properties, as Gatsby does not have access to window during build time and will throw an error in production.

And that’s it! Feel free to play around with different custom values in the entry and exit state of each TransitionLink, or look into using variants and staggerChildren for even more interesting animations once a page has entered.