Auth0 is the enterprise-grade choice for authentication when you need advanced customisation, compliance certifications, or global scalability beyond what Clerk offers. The Next.js SDK (v4) handles session management, route protection, and token handling through a single middleware entry point. This guide covers the complete setup.
Install and Configure
npm install @auth0/nextjs-auth0# .env.local
AUTH0_SECRET='use [openssl rand -hex 32] to generate'
APP_BASE_URL='http://localhost:3000'
AUTH0_DOMAIN='YOUR_DOMAIN.auth0.com'
AUTH0_CLIENT_ID='your-client-id'
AUTH0_CLIENT_SECRET='your-client-secret'
# Only needed if you call an API and request an access token:
AUTH0_AUDIENCE='https://api.yourservice.com'
AUTH0_SCOPE='openid profile email read:documents'Create the Auth0 Client and Middleware
// lib/auth0.ts
import { Auth0Client } from '@auth0/nextjs-auth0/server';
// audience/scope are NOT read from env automatically in v4 -
// pass them explicitly so getAccessToken() returns a real API token.
export const auth0 = new Auth0Client({
authorizationParameters: {
scope: process.env.AUTH0_SCOPE ?? 'openid profile email',
audience: process.env.AUTH0_AUDIENCE,
},
});
// middleware.ts (project root, next to package.json)
import type { NextRequest } from 'next/server';
import { auth0 } from './lib/auth0';
export async function middleware(request: NextRequest) {
return await auth0.middleware(request);
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};A single root middleware.ts intercepts every request and mounts the auth routes automatically: /auth/login, /auth/logout, /auth/callback, and /auth/profile. The old catch-all route handler is gone - the middleware handles everything, using the shared Auth0Client from lib/auth0.ts.
Wrap App with Auth0Provider (Optional)
In v4 the provider is optional. You only need Auth0Provider if you want the useUser() hook in client components to hydrate from the server-rendered session. Server components read the session directly via auth0.getSession() without it.
// app/layout.tsx
import { Auth0Provider } from '@auth0/nextjs-auth0';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<Auth0Provider>{children}</Auth0Provider>
</body>
</html>
);
}Login and Logout Links
// Client component
'use client';
import { useUser } from '@auth0/nextjs-auth0';
export function AuthButton() {
const { user, isLoading } = useUser();
if (isLoading) return <span>Loading...</span>;
if (user) {
return (
<div>
<span>{user.name}</span>
<a href="/auth/logout">Logout</a>
</div>
);
}
return <a href="/auth/login">Login</a>;
}Protect Server Components
// app/dashboard/page.tsx
import { auth0 } from '@/lib/auth0';
import { redirect } from 'next/navigation';
export default async function Dashboard() {
const session = await auth0.getSession();
if (!session) redirect('/auth/login');
return <div>Welcome, {session.user.name}</div>;
}Protect API Routes
// app/api/documents/route.ts
import { auth0 } from '@/lib/auth0';
export async function GET() {
const session = await auth0.getSession();
if (!session) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
const docs = await getDocumentsForUser(session.user.sub);
return Response.json(docs);
}Getting the Access Token for Downstream API Calls
// When your Next.js app calls another API on behalf of the user
import { auth0 } from '@/lib/auth0';
export async function POST(req: Request) {
// getAccessToken() returns { token, expiresAt, scope, ... }
const { token } = await auth0.getAccessToken();
// Call your own API or a third-party API with the user's token
const response = await fetch('https://api.yourservice.com/data', {
headers: { Authorization: `Bearer ${token}` },
});
return Response.json(await response.json());
}Clerk vs Auth0: When to Choose Auth0
| Factor | Choose Clerk | Choose Auth0 |
|---|---|---|
| Setup speed | Faster (5 min) | Slower (20-30 min) |
| Next.js integration | Purpose-built | Good but more config |
| Enterprise SSO | Yes (SAML) | Yes (SAML + more protocols) |
| Compliance certs | SOC 2 | SOC 2, ISO 27001, HIPAA, PCI DSS |
| Actions / customisation | Limited | Extensive (Actions, Rules, Hooks) |
| Pricing at scale | Scales well | Gets expensive at 50k+ MAU |
| Metadata | Value |
|---|---|
| Title | Auth0 Setup for Next.js: Complete Guide from Installation to Protected API Routes |
| Tool | Auth0 |
| Primary SEO keyword | auth0 next.js setup |
| Secondary keywords | auth0 nextjs-auth0, auth0 app router, auth0 protect routes, auth0 session |
| Estimated read time | 8 minutes |
| Research date | 2026-04-14 |