Implementing Protected Routes in React: A Step-by-Step Guide


In modern web applications, protecting certain pages from unauthenticated users is essential. This tutorial walks you through how to implement protected routes in a React app. You’ll learn how to restrict access to specific components unless the user is authenticated.
Step 1: Set Up a React Project
If you don’t already have a React project, start by creating one:
npx create-react-app protected-routes-demo
cd protected-routes-demo
npm start
Step 2: Install React Router
Install React Router for routing support:
npm install react-router-dom
Step 3: Create a Basic Folder Structure
Your project structure should look like this:
src/
│
├── components/
│ ├── Home.js
│ ├── Login.js
│ ├── Dashboard.js
│ └── ProtectedRoute.js
│
├── App.js
└── index.js
Step 4: Create Pages (Components)
Home.js
import React from 'react';
const Home = () => {
return <h2>Home Page (Public)</h2>;
};
export default Home;
Login.js
import React from 'react';
import { useNavigate } from 'react-router-dom';
const Login = ({ setAuth }) => {
const navigate = useNavigate();
const handleLogin = () => {
// Simulate login
localStorage.setItem('isAuthenticated', 'true');
setAuth(true);
navigate('/dashboard');
};
return (
<div>
<h2>Login Page</h2>
<button onClick={handleLogin}>Login</button>
</div>
);
};
export default Login;
Dashboard.js
import React from 'react';
const Dashboard = () => {
return <h2>Dashboard (Protected)</h2>;
};
export default Dashboard;
Step 5: Create the ProtectedRoute Component
ProtectedRoute.js
import React from 'react';
import { Navigate } from 'react-router-dom';
const ProtectedRoute = ({ isAuthenticated, children }) => {
if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}
return children;
};
export default ProtectedRoute;
This component checks the authentication status and redirects unauthenticated users to the login page.
Step 6: Set Up Routing in App.js
App.js
import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './components/Home';
import Login from './components/Login';
import Dashboard from './components/Dashboard';
import ProtectedRoute from './components/ProtectedRoute';
function App() {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const auth = localStorage.getItem('isAuthenticated') === 'true';
setIsAuthenticated(auth);
}, []);
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login setAuth={setIsAuthenticated} />} />
<Route
path="/dashboard"
element={
<ProtectedRoute isAuthenticated={isAuthenticated}>
<Dashboard />
</ProtectedRoute>
}
/>
</Routes>
</Router>
);
}
export default App;
Step 7: Test the Protected Route
Start your app with
npm start
.Go to
/dashboard
directly in the browser. You'll be redirected to/login
.After logging in, you'll be redirected to the dashboard.
Refresh the dashboard page — the app will remember your login using
localStorage
.
Final Notes
In production, don’t rely solely on
localStorage
for authentication. Use JWT tokens and server-side validation.You can extend the
ProtectedRoute
to check for user roles or permissions.
This setup gives you a clean and reusable way to guard your private routes in React using React Router v6.
Subscribe to my newsletter
Read articles from Chris Tiquis directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
