React
Beginner
1 min read
Protected Routes and Navigation Guards
Example
import {
Navigate, Outlet, useLocation, useNavigate
} from 'react-router-dom';
import { useAuth } from './AuthContext';
// ── Guard component ────────────────────────────────────────────────────────
function RequireAuth() {
const { user } = useAuth();
const location = useLocation();
if (!user) {
// Redirect to /login, preserving the attempted URL
return <Navigate to="/login" state={{ from: location }} replace />;
}
return <Outlet />;
}
// ── Route tree with protected section ─────────────────────────────────────
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="login" element={<LoginPage />} />
{/* All routes inside here require auth */}
<Route element={<RequireAuth />}>
<Route path="dashboard" element={<Dashboard />} />
<Route path="settings" element={<Settings />} />
</Route>
</Route>
</Routes>
</BrowserRouter>
);
}
// ── Login page redirects back to original URL ──────────────────────────────
function LoginPage() {
const { login } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const from = location.state?.from?.pathname ?? '/dashboard';
async function handleSubmit(e) {
e.preventDefault();
await login({ email: e.target.email.value });
navigate(from, { replace: true });
}
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" placeholder="Email" />
<button type="submit">Sign in</button>
</form>
);
}