Route Protection
Protect routes in React applications — the Protected component, useProtected hook, and redirect patterns with the HelloJohn React SDK.
Route Protection
@hellojohn/react provides tools to restrict route access to authenticated users, specific roles, and organization members.
<Protected>
Wrap any route or component to require authentication:
import { Protected } from "@hellojohn/react";
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route
path="/dashboard"
element={
<Protected redirectTo="/sign-in">
<Dashboard />
</Protected>
}
/>
</Routes>
);
}Props:
| Prop | Type | Default | Description |
|---|---|---|---|
redirectTo | string | "/sign-in" | Redirect URL if not authenticated |
fallback | ReactNode | null | Element to show while loading |
role | string | — | Require a specific organization role |
orgId | string | — | Require membership in a specific org |
Protecting by Role
// Only org owners and admins can access
<Protected role="admin" redirectTo="/dashboard">
<AdminSettings />
</Protected>
// Owners only
<Protected role="owner" redirectTo="/dashboard">
<BillingPage />
</Protected>Next.js App Router
Wrap layouts with <Protected> to protect entire route segments:
// app/dashboard/layout.tsx
import { Protected } from "@hellojohn/react";
export default function DashboardLayout({ children }) {
return (
<Protected redirectTo="/sign-in">
<DashboardShell>{children}</DashboardShell>
</Protected>
);
}useProtected Hook
For programmatic protection:
import { useProtected } from "@hellojohn/react";
function SecurePage() {
// Redirects to /sign-in if not authenticated
// Returns null while loading
const { user } = useProtected({ redirectTo: "/sign-in" });
if (!user) return null;
return <div>Hello, {user.name}</div>;
}Options:
| Option | Type | Description |
|---|---|---|
redirectTo | string | Where to send unauthenticated users |
role | string | Required organization role |
onUnauthenticated | () => void | Custom handler instead of redirect |
Conditional Rendering
Show content based on authentication state without redirecting:
import { useSession, useUser } from "@hellojohn/react";
function NavBar() {
const { session } = useSession();
const { user } = useUser();
return (
<nav>
<Logo />
{session ? (
<UserButton />
) : (
<a href="/sign-in">Sign in</a>
)}
</nav>
);
}Role-Based Access Control
Combine useOrganization with conditional rendering for RBAC:
import { useOrganization } from "@hellojohn/react";
function DeleteOrgButton() {
const { membership } = useOrganization();
// Only show for owners
if (membership?.role !== "owner") return null;
return (
<button className="btn-destructive" onClick={handleDelete}>
Delete Organization
</button>
);
}Loading States
Always handle the loading state to avoid flashes of unauthenticated content:
import { useSession } from "@hellojohn/react";
function ProtectedPage() {
const { session, isLoading } = useSession();
if (isLoading) {
return <LoadingSpinner />;
}
if (!session) {
// Redirect programmatically
window.location.href = "/sign-in";
return null;
}
return <PageContent />;
}Related
Pre-built Components
Drop-in UI components for authentication flows — sign-in form, sign-up form, user button, and organization switcher with the HelloJohn React SDK.
Auth Operations
Authentication operations with the HelloJohn JavaScript SDK — sign in, sign up, sign out, OAuth, and magic links in vanilla JS environments.