When building single-page applications (SPAs) with React, it is not uncommon to require certain routes to only be accessible to authenticated users. For instance, a user’s profile page or a settings page might be behind a layer of authentication to protect sensitive information. In this blog post, we’ll walk through creating a Protected Route component using React Router, an industry-standard library for routing in React applications.
What Is a Protected Route?
A Protected Route in React Router is a way to restrict access to certain components or pages in your app based on user authentication. If a user is not authenticated, attempting to access a protected route will redirect them to a login page or another appropriate component.
Setting Up Your React Application
First, make sure that you have a basic React application set up. You can quickly create one using Create React App:
npx create-react-app protected-routes-example cd protected-routes-example npm install react-router-dom
Creating a Basic Authentication Context
For this example, let’s create a simple Context to handle authentication state. This will manage whether a user is logged in or not.
// AuthContext.js import React, { createContext, useContext, useState } from 'react'; const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [isAuthenticated, setIsAuthenticated] = useState(false); const login = () => setIsAuthenticated(true); const logout = () => setIsAuthenticated(false); return ( <AuthContext.Provider value={{ isAuthenticated, login, logout }}> {children} </AuthContext.Provider> ); }; export const useAuth = () => { return useContext(AuthContext); };
Creating the Protected Route Component
Next, we’ll create our Protected Route component. This component will check if the user is authenticated and either render the requested component or redirect them to the login page.
// ProtectedRoute.js import React from 'react'; import { Route, Redirect } from 'react-router-dom'; import { useAuth } from './AuthContext'; const ProtectedRoute = ({ component: Component, ...rest }) => { const { isAuthenticated } = useAuth(); return ( <Route {...rest} render={props => isAuthenticated ? ( <Component {...props} /> ) : ( <Redirect to="/login" /> ) } /> ); }; export default ProtectedRoute;
Setting Up Routing
Now we can set up our main application with routing and integrate our protected route. We’ll also create a login and home component for demonstration purposes.
// App.js import React from 'react'; import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'; import { AuthProvider, useAuth } from './AuthContext'; import ProtectedRoute from './ProtectedRoute'; const Home = () => <h2>Home Page</h2>; const Login = () => { const { login } = useAuth(); const handleLogin = () => { login(); } return ( <div> <h2>Login Page</h2> <button onClick={handleLogin}>Login</button> </div> ); }; const Profile = () => <h2>User Profile Page</h2>; const App = () => { return ( <AuthProvider> <Router> <nav> <Link to="/">Home</Link> <Link to="/login">Login</Link> <Link to="/profile">Profile</Link> </nav> <Switch> <Route path="/" exact component={Home} /> <Route path="/login" component={Login} /> <ProtectedRoute path="/profile" component={Profile} /> </Switch> </Router> </AuthProvider> ); }; export default App;
How It Works
-
Auth Context: We begin by creating the
AuthContext
which will hold our authentication state and provide methods to log in and log out. -
Protected Route: The
ProtectedRoute
checks if the user is authenticated. If they are, it renders the requested component. If not, it redirects the user to the login page. -
Routing: In our main
App
component, we set up routing usingreact-router-dom
. We include links for Home, Login, and Profile. The Profile route is protected, meaning only authenticated users will have access. -
Login Functionality: In our Login component, we invoke the
login
method fromAuthContext
to set the user as authenticated when they click the login button.
This is a straightforward way to implement protected routes in a React application. You can expand this further by adding logout functionality and better error handling or using a real authentication service.