Frontend Patterns

Pattern

Route Guard

Protect routes with authentication, authorization, or validation checks before rendering.

Route Guard

Problem

Protected content briefly flashes on screen before auth checks redirect users, creating security concerns and poor user experience. Each route must manually check permissions, leading to scattered authentication logic and easy-to-miss security holes.

Solution

Check conditions before allowing navigation to protected routes, redirecting unauthorized users. This enforces authentication and authorization requirements at the routing level.

Example

This example shows a route guard that checks authentication before rendering protected content, redirecting unauthorized users to the login page.

function ProtectedRoute({ children }) {
  // Check if user is authenticated
  const { user } = useAuth();

  // Redirect to login if not authenticated
  if (!user) {
    return <Navigate to="/login" />;
  }

  // Render protected content only if authenticated
  return children;
}

// Wrap protected routes with the guard
<Route path="/dashboard" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />

Benefits

  • Centralizes authentication logic instead of scattering it across components.
  • Prevents protected content from briefly flashing before redirects.
  • Makes security requirements explicit and easier to audit.
  • Provides a declarative way to enforce access control.

Tradeoffs

  • Can create poor UX if redirects aren’t handled smoothly.
  • May need complex logic for role-based or conditional access.
  • Requires careful handling of redirect destinations and return URLs.
  • Can make testing harder if guards are tightly coupled to routing.
Stay Updated

Get New Patterns
in Your Inbox

Join thousands of developers receiving weekly insights on frontend architecture patterns

No spam. Unsubscribe anytime.