InterviewHubPRO
Section Overview
Q350

Question 350 of 445

Part 10: Modern React 18, React 19 & Next.js Patterns (317 - 353)

79%
React & Modern Frontend (445 Qs)•Part 10: Modern React 18, React 19 & Next.js Patterns (317 - 353)

How do you implement protected/private routes?

A protected (or private) route only renders its content when the user meets some condition (usually "is authenticated"), otherwise it redirects them elsewhere (e.g., to /login). In React Router v6+, the cleanest way is a small wrapper component that renders <Outlet /> for its children or a <Navigate> redirect:

jsx
import { Navigate, Outlet, useLocation } from "react-router-dom";

function RequireAuth() {
const { user } = useAuth(); // your own auth hook/context
const location = useLocation();

if (!user) {
  // Redirect to login, remembering where the user was headed
  return <Navigate to="/login" state={{ from: location }} replace />;
}

return <Outlet />; // render the matched child route
}
jsx
import { Routes, Route } from "react-router-dom";

function App() {
return (
  <Routes>
    <Route path="/login" element={<Login />} />

    {/* Every nested route below requires auth */}
    <Route element={<RequireAuth />}>
      <Route path="/dashboard" element={<Dashboard />} />
      <Route path="/settings" element={<Settings />} />
    </Route>
  </Routes>
);
}

After a successful login, read location.state?.from (set above) and navigate(from, { replace: true }) to send the user back to the page they originally tried to reach.

Key points:

  • Wrapping with a layout route (<Route element={<RequireAuth />}>) that renders <Outlet /> lets you protect many nested routes at once, instead of guarding each element individually.
  • Use replace on the redirect so the protected URL isn't left in history (prevents "back button" from flashing the protected page).
  • For role-based protection (e.g., admin-only), generalize RequireAuth to accept an allowedRoles prop and check both authentication and authorization.
  • Client-side route guards are a UX convenience, not a security boundary — always enforce access control on the server/API too.