Documentation Index
Fetch the complete documentation index at: https://mintlify.com/auth0/nextjs-auth0/llms.txt
Use this file to discover all available pages before exploring further.
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