How to protect routes in React Router
Protecting routes based on authentication status is essential for secure React applications, ensuring only authorized users can access certain pages. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented authentication guards in countless admin dashboards and enterprise applications. From my 25 years of experience in web development and 11 years with React, the most effective and scalable approach is to create a higher-order component that wraps protected routes and checks authentication status. This pattern provides clean separation of concerns and reusable protection logic.
Use a higher-order component to check authentication status and redirect unauthorized users to the login page.
import { Navigate } from 'react-router-dom'
function ProtectedRoute({ children, isAuthenticated }) {
if (!isAuthenticated) {
return <Navigate to='/login' replace />
}
return children
}
// Usage in your routes
function App() {
const [isAuthenticated, setIsAuthenticated] = useState(false)
return (
<Routes>
<Route path='/login' element={<LoginPage />} />
<Route
path='/dashboard'
element={
<ProtectedRoute isAuthenticated={isAuthenticated}>
<DashboardPage />
</ProtectedRoute>
}
/>
</Routes>
)
}
The ProtectedRoute component accepts an isAuthenticated boolean prop and the child components to protect. If the user is not authenticated, it renders the Navigate component to redirect to the login page. The replace prop ensures the protected route is replaced in the browser history, preventing users from navigating back to it after logout. If authenticated, it renders the child components normally.
This is the same secure pattern we use in CoreUI Pro admin templates to protect enterprise dashboards.
For role-based access, extend this component to accept a requiredRole prop and compare it with the user’s current role.



