How to Secure Routes in React Router
Securing routes in a React application is essential for protecting sensitive pages and user data from unauthorized access. This article provides a straightforward guide on how to implement protected routes in React Router, covering the creation of a reusable wrapper component, managing authentication state, and redirecting unauthorized users to a login page.
To secure routes in React Router (v6 and above), you need to create a route guard. This is typically a component that checks the user’s authentication status before rendering the requested page. If the user is authenticated, the component grants access; otherwise, it redirects them to a public page, such as a login screen.
Step 1: Create the ProtectedRoute Component
The ProtectedRoute component acts as a gatekeeper. It
checks an authentication condition (like a token in local storage or a
state variable from a React Context) and decides whether to render the
child components or trigger a redirect.
import { Navigate, Outlet } from 'react-router-dom';
const ProtectedRoute = ({ isAuthenticated }) => {
if (!isAuthenticated) {
// Redirect unauthorized users to the login page
return <Navigate to="/login" replace />;
}
// Render the child routes if authenticated
return <Outlet />;
};
export default ProtectedRoute;In this component: * Navigate: A React
Router component used to programmatically redirect users. The
replace prop ensures the unauthorized page is replaced in
the browser history, preventing users from clicking “Back” to access the
secured route. * Outlet: A placeholder
component that renders the child routes matched by the router.
Step 2: Implement the Protected Routes in Your App Router
Next, integrate the ProtectedRoute component into your
main router configuration. Wrap the routes you want to protect inside
the ProtectedRoute element.
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { useState } from 'react';
import ProtectedRoute from './ProtectedRoute';
import Login from './pages/Login';
import Dashboard from './pages/Dashboard';
import Settings from './pages/Settings';
import Home from './pages/Home';
function App() {
// Replace this state with your actual authentication logic (e.g., Context API, Redux, or Auth0)
const [isAuthenticated, setIsAuthenticated] = useState(false);
return (
<Router>
<Routes>
{/* Public Routes */}
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login setIsAuthenticated={setIsAuthenticated} />} />
{/* Secured Routes */}
<Route element={<ProtectedRoute isAuthenticated={isAuthenticated} />}>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Route>
</Routes>
</Router>
);
}
export default App;How It Works
By nesting the /dashboard and /settings
routes inside the ProtectedRoute route, React Router will
check the isAuthenticated prop before loading either page.
If a non-logged-in user attempts to navigate directly to
/dashboard, the ProtectedRoute intercepts the
request and instantly redirects them to /login.