Skip to main content
withPageAuthRequired is a higher-order component (HOC) that protects client-side pages by redirecting unauthenticated users to the login page. After login, users are automatically returned to the page they were trying to access.
This is the client-side version for React components. For server-side page protection, see withPageAuthRequired (Server).

Usage

Basic Protection

'use client';

import { withPageAuthRequired } from '@auth0/nextjs-auth0';

function ProfilePage({ user }) {
  return (
    <div>
      <h1>Welcome, {user.name}!</h1>
      <img src={user.picture} alt={user.name} />
      <p>Email: {user.email}</p>
    </div>
  );
}

export default withPageAuthRequired(ProfilePage);

Custom Redirect Path

export default withPageAuthRequired(ProfilePage, {
  returnTo: '/dashboard'
});

Custom Loading State

export default withPageAuthRequired(ProfilePage, {
  onRedirecting: () => (
    <div className="flex items-center justify-center min-h-screen">
      <div className="spinner" />
      <p>Redirecting to login...</p>
    </div>
  )
});

Custom Error Handling

export default withPageAuthRequired(ProfilePage, {
  onError: (error) => (
    <div className="error-container">
      <h1>Authentication Error</h1>
      <p>{error.message}</p>
      <a href="/auth/login">Try logging in again</a>
    </div>
  )
});

Signature

function withPageAuthRequired<P extends object>(
  Component: ComponentType<P & UserProps>,
  options?: WithPageAuthRequiredOptions
): React.FC<P>

Parameters

Component
ComponentType<P & UserProps>
required
The React component to protect. The component will receive a user prop containing the authenticated user’s profile.
function MyPage({ user }: { user: User }) {
  return <div>Hello {user.name}</div>;
}

export default withPageAuthRequired(MyPage);
options
WithPageAuthRequiredOptions
Configuration options for the HOC.

Return Value

Returns a wrapped React component that:
  1. Checks if the user is authenticated using useUser()
  2. Redirects to login if not authenticated
  3. Shows the loading state while checking authentication
  4. Shows the error state if authentication check fails
  5. Renders the protected component with the user prop if authenticated

UserProps Type

The protected component receives a user prop with the following type:
interface UserProps {
  user: User;
}

interface User {
  sub: string;                  // User ID (required)
  name?: string;                // Full name
  nickname?: string;            // Nickname
  given_name?: string;          // First name
  family_name?: string;         // Last name
  picture?: string;             // Profile picture URL
  email?: string;               // Email address
  email_verified?: boolean;     // Email verification status
  org_id?: string;              // Organization ID
  [key: string]: any;           // Additional custom claims
}

How It Works

  1. Authentication Check: Uses useUser() to fetch the current user
  2. Redirect Logic: If not authenticated, redirects to /auth/login?returnTo=<current-page>
  3. Return Path: After login, Auth0 redirects back to the returnTo URL
  4. Loading State: Shows onRedirecting() while checking authentication
  5. Error State: Shows onError() if the profile fetch fails

Configuration

The login endpoint can be customized using the NEXT_PUBLIC_LOGIN_ROUTE environment variable:
NEXT_PUBLIC_LOGIN_ROUTE=/api/custom-login

Examples

Complete Protected Page

'use client';

import { withPageAuthRequired } from '@auth0/nextjs-auth0';
import type { User } from '@auth0/nextjs-auth0/types';

interface DashboardPageProps {
  user: User;
}

function DashboardPage({ user }: DashboardPageProps) {
  return (
    <div>
      <header>
        <h1>Dashboard</h1>
        <div>
          <img src={user.picture} alt={user.name} />
          <span>{user.name}</span>
        </div>
      </header>
      <main>
        <p>Welcome to your dashboard, {user.given_name}!</p>
      </main>
    </div>
  );
}

export default withPageAuthRequired(DashboardPage, {
  onRedirecting: () => (
    <div className="loading-screen">
      <div className="spinner" />
      <p>Loading your dashboard...</p>
    </div>
  ),
  onError: (error) => (
    <div className="error-screen">
      <h1>Oops! Something went wrong</h1>
      <p>{error.message}</p>
      <button onClick={() => window.location.reload()}>
        Try Again
      </button>
    </div>
  )
});

With TypeScript

import { withPageAuthRequired } from '@auth0/nextjs-auth0';
import type { UserProps } from '@auth0/nextjs-auth0';

interface ProfilePageProps {
  theme: 'light' | 'dark';
}

function ProfilePage({ user, theme }: ProfilePageProps & UserProps) {
  return (
    <div className={theme}>
      <h1>{user.name}'s Profile</h1>
    </div>
  );
}

export default withPageAuthRequired(ProfilePage);

Pages Router Example

// pages/profile.tsx
import { withPageAuthRequired } from '@auth0/nextjs-auth0';
import type { UserProps } from '@auth0/nextjs-auth0';

function Profile({ user }: UserProps) {
  return <div>Hello {user.name}</div>;
}

export default withPageAuthRequired(Profile);

App Router Example

// app/profile/page.tsx (Client Component)
'use client';

import { withPageAuthRequired } from '@auth0/nextjs-auth0';
import type { UserProps } from '@auth0/nextjs-auth0';

function ProfilePage({ user }: UserProps) {
  return <div>Hello {user.name}</div>;
}

export default withPageAuthRequired(ProfilePage);

Client vs Server Protection

FeatureClient (withPageAuthRequired)Server (withPageAuthRequired)
ExecutionBrowserServer
RedirectClient-side navigationServer-side redirect (302)
SEOPoor (protected content not rendered)Good (redirect before render)
PerformanceFlash of loading stateNo flash, immediate redirect
Use CaseInteractive client componentsStatic pages, SEO-important pages
Recommendation: Prefer server-side protection for better UX and SEO. Use client-side protection only for dynamic client components that can’t be server-rendered.

Notes

  • Requires Auth0Provider to be configured in your app
  • The protected component must be a client component (marked with "use client")
  • The user prop is automatically injected into your component
  • For server-side protection with better performance and SEO, use the server version

Build docs developers (and LLMs) love