Skip to content
Related Articles

Related Articles

Page transition in React.js using Framer Motion

Improve Article
Save Article
  • Last Updated : 28 Mar, 2022
Improve Article
Save Article

The React.js framework makes it possible to create single-page applications without reloading the page when visiting different links. As you move from one link to another, the change is so rapid that it is difficult to tell if the content has actually changed. Thus, we can implement transition behavior while navigating through different links or routes on a website. This improves the User Experience of the application. In this article, we will be using the Framer motion package to create page transitions. 

Approach: We’ll create a portfolio application for GeeksforGeeks. We will create a Navbar component. With the Navbar component, we can navigate to different components, such as Home, About, and Contact. We will use framer motion to add page transitions to different routes in our React application.

Follow the steps below and get started. 

Step 1: Create React application

Make a project directory, head over to the terminal, and create a React app named “portfolio” using the following command:

npx create-react-app portfolio 

After the portfolio app is created, switch to the new folder portfolio using the following command:

cd portfolio

Step 2: The Directory structure currently looks like this:

Final Project Structure 

Step 3: Install the required packages.

  • react-router-dom (v5): for routing 
  • framer-motion: for creating page transitions 

Installing Dependencies 

Install the following dependencies by using the following command:

npm i react-router-dom framer-motion

Step 4: Add code to your index.html file.

Include the following code in your index.html file, located in the public folder of your project directory. We will use bootstrap to build our Navbar component. Import the bootstrap CDN into your index.html as follows:

Links: Put the following code at the end of the body.

<script src=”https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js” integrity=”sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p” crossorigin=”anonymous”></script>

Links: Put the following code at the end of the head:

<link rel=”stylesheet” href=”https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css” integrity=”sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm” crossorigin=”anonymous”>

index.html: Add the following code to the index.html file:

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" 
          content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" 
          content="Web site created using create-react-app" />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link href=
    rel="stylesheet" 
       integrity=
"sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" 
    crossorigin="anonymous">
    <title>React App</title>
</head>
<body>
    <div id="root"></div>
  
    <script src=
    integrity=
"sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" 
    crossorigin="anonymous">
     </script>
</body>
</html>


Step 5: Creating the transitions for all the routes. We will be creating a simple fade-in and fade-out animation. 

In your Src folder, create a new folder named Components. Inside the Components folder, create a new file called Transitions.js.

We will create a transition component and pass in the prop for the children, so it renders whatever is wrapped in it. When the component is mounted, we will need to wrap it in a Framer Motion component called “motion.div”. 

So, we will import the motion component:

import { motion } from 'framer-motion';

We’re going to add certain props that are defined in framer motion, such as

  • initial: This indicates how the component will look at the beginning of the animation.
  • animate: This is what the component looks like after it has finished animating.
  • exit: This defines the style of the component after it has animated out of the animation.
  • transition: This specifies how long we want the duration to last.

We will configure the animation props and pass them in the variants which enable us to define the animation state. 

At first, the prop is invisible. Initially, the opacity is kept at 0 to make it invisible. It will then animate for 3 seconds to become visible. This creates a simple fade-in and fade-out animation. 

Transition.js: Add the following code to the Transition.js file:

Javascript




import { motion } from "framer-motion";
const animationConfiguration = {
    initial: { opacity: 0 },
    animate: { opacity: 1 },
    exit: { opacity: 0 },
};
const Transitions = ({ children }) => {
    return (
        <motion.div
            variants={animationConfiguration}
            initial="initial"
            animate="animate"
            exit="exit"
            transition={{ duration: 3 }}
        >
            {children}
        </motion.div>
    );
};
export default Transitions;


Step 6: Creating the Home component for Homepage. In the Components folder, create a new file named Home.js. We will create a Home component for the homepage and wrap the component inside the Transitions Component to create a page transition. 

Javascript




import React from 'react'
import Transitions from './Transition'
  
const Home = () => {
    return (
        <>
            <Transitions>
                <h3 className='mt-5' 
                    style={{ color: 'green' }}>
                    Welcome to GeeksforGeeks
                </h3>
            </Transitions>
        </>
    )
}
  
export default Home


Step 7: Creating the About Component for the About Us page. 

We will create a new file in the Components folder called About.js and then wrap the About component inside the Transitions Component to create an animation as we switch between routes. The About component consists of a brief description of GeeksforGeeks. 

  • About Us: Add the following code in the About.js file. 

Javascript




import React from 'react'
import Transitions from './Transition'
  
const About = () => {
    return (
        <>
            <Transitions>
                <h2 className='mt-5 text-center' 
                    style={{ color: 'green' }}>
                    GeeksforGeeks is a computer 
                    science portal for Geeks.
                </h2>
            </Transitions>
        </>
    )
}
  
export default About


 Step 8: Creating the Contact component for Contact Us page. 

We will create a new file in the Components folder called Contact.js and then wrap the About component inside the Transitions Component to create an animation as we switch between routes. The Contact component contains GeeksforGeeks’s contact address. 

  • Contact Us: Add the following code to the Contact.js file.

Javascript




import React from 'react'
import Transitions from './Transition'
  
const Contact = () => {
    return (
        <>
            <Transitions>
                <h3 className='mt-5' style={{ color: 'green' }}>
                    Address : GeeksforGeeks
                    <br />
                    5th & 6th Floor, Royal Kapsons, A- 118,
                    Sector- 136, Noida, Uttar Pradesh (201305)
                </h3>
            </Transitions>
        </>
    )
}
  
export default Contact


Step 9: Creating the Navbar Component 

Create a new file in your components folder called Navbar.js. We’ll make a Navbar using Bootstrap and add the links for Home, About Us, and Contact Us. We will import the Link from the react-router-dom package.  

import {Link} from 'react-router-dom'

Javascript




import React from 'react'
import { Link } from 'react-router-dom'
  
const Navbar = () => {
    return (
        <>
            <nav className="navbar navbar-expand-lg 
                navbar-light bg-light">
                <div className="container-fluid">
                    <a className="navbar-brand" href="/">
                        GeeksforGeeks
                    </a>
                    <button className="navbar-toggler" 
                        type="button" data-bs-toggle="collapse" 
                        data-bs-target="#navbarNav" aria-controls="navbarNav" 
                        aria-expanded="false" aria-label="Toggle navigation">
                        <span className="navbar-toggler-icon"></span>
                    </button>
                    <div className="collapse navbar-collapse" id="navbarNav">
                        <ul className="navbar-nav">
                            <li className="nav-item">
                                <Link className="nav-link active" 
                                    aria-current="page" to="/">Home</Link>
                            </li>
                            <li className="nav-item">
                                <Link className="nav-link" to="/about">
                                    About Us
                                </Link>
                            </li>
                            <li className="nav-item">
                                <Link className="nav-link" to="/contact">
                                    Contact Us
                                </Link>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </>
    )
}
  
export default Navbar


Step 10: Passing the components in the root App component. In the App.js file, we will create an Animated Component.

Framer Motion consists of the AnimatePresence Component, which tracks the unmounting of components. It fires the exit props when the component unmounts. We will pass the exitBeforeEnter prop that makes sure to render one component at a time. 

So, we will import AnimatePresence:

import { AnimatePresence } from 'framer-motion';

We will set up routing for all the routes using react-router-dom inside the Animated Component. So, we will import the Router, Switch and Link from the react-router-dom.

import { BrowserRouter as Router, Switch, 
    Route, Link } from "react-router-dom";

The animate presence will work if the child component changes. In our case, we want a transition between pages. Our switch is a child component, and we need to pass it a unique key. Since we want a transition on path change, we’ll pass the path as a key in, using the UseLocation hook.   

We will pass our Navbar component and the Animated Component to the root App component.  

  • App.js: Add the following code in the App.js file.

Javascript




import './App.css';
import React from "react"
import { BrowserRouter as Router, Switch, 
    Route, Link } from "react-router-dom";
import { useLocation } from 'react-router-dom';
import About from './Components/About';
import Contact from './Components/Contact';
import Home from './Components/Home';
import Navbar from './Components/Navbar';
import { AnimatePresence } from 'framer-motion';
  
const Animated = () => {
    const location = useLocation();
    return (
        <AnimatePresence exitBeforeEnter >
  
            <Switch location={location} 
                key={location.pathname}>
                <Route exact path="/" component={Home}></Route>
  
                <Route exact path="/about" 
                    component={About}></Route>
                <Route exact path="/contact" 
                    component={Contact}></Route>
            </Switch>
        </AnimatePresence>
    )
}
  
function App() {
    return (
        <div className="App">
            <>
                <Router>
                    <Navbar />
                    <Animated />
                </Router>
            </>
        </div>
    );
}
  
export default App;


Step 11: Your index.js file should look like this. The index.js file serves as the main entry point, and inside it, the App.js file is rendered at the root ID of the DOM.

Javascript




import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
  
  
ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById('root')
);


The GeeksforGeeks portfolio Application is ready. 

Step to run the Application: Run the application by using the following command:

npm start

Output: By default, the React project will run on port 3000. You can access it at localhost:3000 on your browser.  We will observe transitions between the pages as we navigate through them. 

GeeksforGeeks Portfolio Application: Page Transitions 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!