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

Chris TiquisChris Tiquis
3 min read

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

  1. Start your app with npm start.

  2. Go to /dashboard directly in the browser. You'll be redirected to /login.

  3. After logging in, you'll be redirected to the dashboard.

  4. 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.

0
Subscribe to my newsletter

Read articles from Chris Tiquis directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chris Tiquis
Chris Tiquis