Protected Routes
Implement protected routes in React — the pattern for restricting access to authenticated users and specific roles. Learn the correct implementation pattern used in production applications.
Last reviewed: January 2025
🔍 What Is It?
A protected route is a route guard — a component that checks a condition before rendering its children. In React Router v6, the pattern uses a layout route:
function RequireAuth() {
const { user, isLoading } = useAuth();
const location = useLocation();
if (isLoading) return <Spinner />;
if (!user) return <Navigate to="/login" state={{ from: location }} replace />;
return <Outlet />; // render the protected route
}This component either renders <Outlet /> (the protected content) or redirects to login.
🎯 Why Do We Need It?
Without route protection:
- →Unauthenticated users can access any URL directly
- →Users with wrong roles can access admin pages
- →Sensitive data is exposed to anyone who knows the URL
Protected routes enforce access control at the routing layer, before any data is fetched or rendered.
🏗️ What Happens in Real Projects?
Every authenticated app needs protected routes:
- →Redirect unauthenticated users to /login
- →After login, redirect back to the page they tried to access
- →Admin-only routes that redirect non-admins to a 403 page
- →Feature-flag routes that redirect users without the feature enabled
⚙️ How It Works
- Create a
RequireAuthlayout route component - It reads auth state from your auth context/store
- If loading: show a spinner (prevents flash of redirect)
- If not authenticated: redirect to /login, preserving the intended destination in state
- If authenticated: render
<Outlet />(the protected content) - After login, read the
fromlocation from state and redirect back
💻 Example
Protected Routes Implementation — Auth guard, role guard, and post-login redirect pattern.
🤔 Common Confusions
❓ Why do I see a flash of the protected content before the redirect?
This happens when auth state initialises as null (unauthenticated) before the session is restored. Fix: add an isLoading state to your auth context. While isLoading is true, show a spinner. Only redirect when isLoading is false AND user is null.
❓ Should I protect routes on the frontend or backend?
Both. Frontend route protection is a UX concern — it prevents rendering the wrong UI and redirects users cleanly. Backend API protection is a security concern — it prevents unauthorised data access. Never rely solely on frontend route protection for security. Always validate auth on every API call.
🚨 Common Production Issues
**Flash of redirect** — Auth loads asynchronously. If you redirect immediately when user is null, you redirect before the session is restored. Always check isLoading before redirecting.
**Lost navigation state** — The from location state is lost if the user refreshes the login page. Handle the fallback: const from = location.state?.from?.pathname ?? "/dashboard".
**Security: Client-side only** — Route guards are a UX improvement, not a security boundary. Always validate tokens on every API request.
✅ Best Practices
Always handle the isLoading state to prevent flash of redirect
Preserve the intended destination in navigation state for post-login redirect
Create separate guards for auth (RequireAuth) and roles (RequireRole)
Never rely on frontend guards alone — always validate on the server
Provide a clear 403 Forbidden page for role violations
🏛️ Architect's Note
Protected routes are a UX layer, not a security layer. The real security is your API — every endpoint must validate the JWT and check permissions server-side. Frontend guards prevent the wrong UI from rendering and provide a good user experience. They are not a substitute for backend security. This distinction is important to communicate clearly to product and business stakeholders.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
↗ Where this topic fits
React Technology Guide
Return to the React learning hub.
Frontend Engineer Career Path
A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.
Python Developer Career Path
A practical route through Python fundamentals, automation, backend basics, testing, projects, interview preparation, and career growth.
Sources
Sources / References
Use these React references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide React learning path
Browse the full React topic collection and learning order on SplashRide.
React Interview Prep
Practice React interview questions and scenario-based answers.
Frontend Engineer Career Path
A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.
Python Developer Career Path
A practical route through Python fundamentals, automation, backend basics, testing, projects, interview preparation, and career growth.
React Router
Master React Router v6 — the standard routing library for React SPAs. Learn route definitions, navigation, URL params, and the patterns senior engineers use in production applications.
React Nested Routes with Outlet, Layouts, and Index Routes
Build nested routes in React Router with Outlet, shared layouts, relative child paths, and index routes. Includes a minimal example and fixes for blank child pages.