The withPageAuthRequired helper protects pages by checking for an active session and redirecting unauthenticated users to the login page.
Usage
The helper works differently for App Router and Pages Router:
// Server Component protection
auth0.withPageAuthRequired(
async function Page() { ... },
options?: WithPageAuthRequiredAppRouterOptions
)
App Router
Server Components
Wrap your Server Component to protect it:
import { auth0 } from '@/lib/auth0';
export default auth0.withPageAuthRequired(
async function Dashboard() {
const session = await auth0.getSession();
return (
<div>
<h1>Dashboard</h1>
<p>Welcome, {session!.user.name}!</p>
</div>
);
},
{ returnTo: '/dashboard' }
);
You must provide the returnTo option for Server Components since they cannot access the URL pathname.
App Router Options
The path to return to after successful authentication.{ returnTo: '/dashboard' }
loginUrl
string
default:"/auth/login"
Custom login URL to redirect unauthenticated users.
Complete App Router Example
import { auth0 } from '@/lib/auth0';
export default auth0.withPageAuthRequired(
async function ProtectedPage() {
const session = await auth0.getSession();
const { token } = await auth0.getAccessToken();
// Fetch protected data
const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${token}`
}
});
const data = await response.json();
return (
<div>
<h1>Protected Page</h1>
<p>User: {session!.user.email}</p>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
},
{
returnTo: '/protected',
loginUrl: '/custom-login'
}
);
Pages Router
getServerSideProps Protection
Wrap getServerSideProps to protect a page:
import { auth0 } from '@/lib/auth0';
import type { InferGetServerSidePropsType } from 'next';
export const getServerSideProps = auth0.withPageAuthRequired();
export default function Dashboard({
user
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<div>
<h1>Dashboard</h1>
<p>Welcome, {user.name}!</p>
</div>
);
}
Custom getServerSideProps
Pass your own getServerSideProps function:
import { auth0 } from '@/lib/auth0';
import type { GetServerSideProps, InferGetServerSidePropsType } from 'next';
type Props = {
user: any;
profile: any;
};
export const getServerSideProps = auth0.withPageAuthRequired<Props>({
async getServerSideProps(ctx) {
const session = await auth0.getSession(ctx.req);
// Fetch additional data
const profile = await fetchUserProfile(session!.user.sub);
return {
props: {
profile
}
};
}
});
export default function Profile({
user,
profile
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<div>
<h1>Profile</h1>
<p>Name: {user.name}</p>
<p>Bio: {profile.bio}</p>
</div>
);
}
Pages Router Options
The path to return to after authentication. Defaults to the current page.
Your custom getServerSideProps function. Props are merged with the user prop.{
async getServerSideProps(ctx) {
return {
props: {
customData: 'value'
}
};
}
}
Complete Pages Router Example
import { auth0 } from '@/lib/auth0';
import type { GetServerSideProps, InferGetServerSidePropsType } from 'next';
type Props = {
user: any;
isAdmin: boolean;
};
export const getServerSideProps = auth0.withPageAuthRequired<Props>({
async getServerSideProps(ctx) {
const session = await auth0.getSession(ctx.req);
// Check admin role
const isAdmin = session!.user['https://example.com/roles']?.includes('admin');
if (!isAdmin) {
return {
redirect: {
destination: '/unauthorized',
permanent: false
}
};
}
return {
props: {
isAdmin
}
};
}
});
export default function Admin({
user,
isAdmin
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<div>
<h1>Admin Panel</h1>
<p>Welcome, {user.name}</p>
</div>
);
}
Client-Side Protection
For Client Components, use the client-side helper:
'use client';
import { withPageAuthRequired } from '@auth0/nextjs-auth0/client';
export default withPageAuthRequired(function Profile({ user }) {
return (
<div>
<h1>Profile</h1>
<p>Welcome, {user.name}</p>
</div>
);
});
The client-side helper uses the useUser() hook and redirects to login if no user is found.
Redirect Behavior
Default Redirect
Unauthenticated users are redirected to /auth/login with a returnTo parameter:
/auth/login?returnTo=/dashboard
After login, users are redirected back to the original page.
Custom Login URL
Specify a custom login URL:
auth0.withPageAuthRequired(
async function Page() { ... },
{
returnTo: '/page',
loginUrl: '/custom-login'
}
);
Conditional Redirects
Implement custom logic in getServerSideProps:
export const getServerSideProps = auth0.withPageAuthRequired({
async getServerSideProps(ctx) {
const session = await auth0.getSession(ctx.req);
// Redirect based on user role
if (!session!.user.email_verified) {
return {
redirect: {
destination: '/verify-email',
permanent: false
}
};
}
return { props: {} };
}
});
Error Handling
Handle authentication errors:
export const getServerSideProps = auth0.withPageAuthRequired({
async getServerSideProps(ctx) {
try {
const session = await auth0.getSession(ctx.req);
// Fetch data...
} catch (error) {
console.error('Error:', error);
return {
redirect: {
destination: '/error',
permanent: false
}
};
}
return { props: {} };
}
});
Router Comparison
| Feature | App Router | Pages Router |
|---|
| Protection level | Server Component | getServerSideProps |
| Syntax | Wrap component | Wrap getServerSideProps |
returnTo required | ✅ Yes | ❌ No (inferred) |
| Custom props merge | ❌ N/A | ✅ Yes |
| Type safety | ✅ Full | ✅ Full |
Common Patterns
Role-Based Access
export const getServerSideProps = auth0.withPageAuthRequired({
async getServerSideProps(ctx) {
const session = await auth0.getSession(ctx.req);
const roles = session!.user['https://example.com/roles'] || [];
if (!roles.includes('admin')) {
return {
redirect: {
destination: '/unauthorized',
permanent: false
}
};
}
return { props: {} };
}
});
Organization Validation
export const getServerSideProps = auth0.withPageAuthRequired({
async getServerSideProps(ctx) {
const session = await auth0.getSession(ctx.req);
const orgId = session!.user.org_id;
if (orgId !== 'org_expected') {
return {
redirect: {
destination: '/wrong-organization',
permanent: false
}
};
}
return { props: {} };
}
});
Email Verification Check
export const getServerSideProps = auth0.withPageAuthRequired({
async getServerSideProps(ctx) {
const session = await auth0.getSession(ctx.req);
if (!session!.user.email_verified) {
return {
redirect: {
destination: '/verify-email',
permanent: false
}
};
}
return { props: {} };
}
});
getSession
Retrieve session data
Protect API Routes
Learn how to protect API routes