ProtectedRoute Route Guards

Last updated: 2026-11-02

ProtectedRoute Route Guards

A route guard checks permissions before the page opens: wrap a route in ProtectedRoute, and when the visitor is not signed in it redirects to /login while remembering the page they came from, so they can be sent back after signing in. React ships no built-in guard, so you build one from conditional rendering plus Navigate or useNavigate, and the guard stays a plain component you can test on its own.

GroupRouting & State Mgmt
KindPattern

ℹ️ Info The editor transpiles JSX to JavaScript and renders the real UI in a sandbox; components mount automatically — no manual render call needed.

📝 Syntax

import { Navigate, Outlet } from 'react-router-dom'

function ProtectedRoute({ isAuth }) {
  if (!isAuth) {
    // Not signed in: redirect to the login page and remember where we came from
    return <Navigate to="/login" replace state={{ from: location.pathname }} />
  }
  return <Outlet />   // Signed in: render the child routes
}

// Usage:
// <Route element={<ProtectedRoute isAuth={user} />}>
//   <Route path="/admin" element={<Admin />} />
// </Route>

⚙️ Parameters

isAuth (custom)The permission check: a boolean, an array of roles or an async state - whatever your session provides.
redirect (custom)Where a rejected visitor goes: a redirect address or a notice UI, designed per project.

Returns:No return value; this is a coding pattern rather than a callable API.

▶ Example

The example runs out of the box: it auto-renders when expanded, and edits take effect instantly.

Output:

Clicking "Admin" while signed out is blocked and lands on the login page; clicking "Sign in and come back" enters the admin panel - the guard flow of a Navigate redirect plus a return after signing in (simulated demo).

💡 Key Points

⚠️ Warning A front-end guard is only a layer of experience: static assets and APIs stay directly reachable, so the server has to check the permissions again for every sensitive piece of data.
💡 Tip Store the source page in the state while redirecting (from: location.pathname) and jump back precisely with navigate(state.from ?? '/home') after signing in.
ℹ️ Info When the permission comes from an async request (a /me endpoint), show a loading state in the guard first and only then let the visitor through, so the login page does not flash by.
More case studies coming soon.

📚 Related Tutorials

❓ FAQ

Q How does the Navigate component differ from useNavigate?
A Navigate redirects as soon as it is rendered, which fits declarative branches in JSX, while useNavigate is an imperative function for event callbacks. Both end up doing the same thing underneath.
Q How do I return to the page the visitor wanted?
A Store state={{ from: location.pathname }} before redirecting, then call navigate(location.state?.from ?? '/home') after a successful sign-in.
Q How do I extend this to role permissions (admin/vip)?
A Swap isAuth for a role check: test allowedRoles.includes(user.role) inside the guard and wrap it in a RoleRoute component so it can be reused.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏