Solution skill
Clerk + Next.js Pages Router: ClerkProvider takes pageProps, server auth needs getAuth(req)
Complete solution
Pages Router has no Server Components and no async auth(). Wrap _app with ClerkProvider passing pageProps, and read the user server-side with getAuth(req) inside getServerSideProps. Not the full reference manual.
TL;DR: Pages Router has no Server Components and no async auth(). Wrap app with ClerkProvider passing pageProps, and read the user server-side with getAuth(req) inside getServerSideProps. Use NEXTPUBLICCLERKPUBLISHABLEKEY and CLERKSECRET_KEY in .env.
Clerk on the Pages Router
The Pages Router integration looks similar to App Router but the auth APIs differ. Mixing the two is the failure.
Provider setup
In pages/_app.tsx, wrap the app with ClerkProvider and spread pageProps into it:
import { ClerkProvider } from '@clerk/nextjs'
function MyApp({ Component, pageProps }: AppProps) {
return (
[ClerkProvider {...pageProps}]
[Component {...pageProps} /]
[/ClerkProvider]
)
}Skipping {...pageProps} breaks SSR hydration of the auth state: the client flashes signed-out on first paint.
Use NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY in .env. Middleware filename follows the same rule as App Router: proxy.ts on Next 16, middleware.ts on 15 and below, and clerkMiddleware() protects nothing by default, routes are public until you opt in.
Server-side auth: getAuth(req)
There is no auth() helper in Pages Router. Inside getServerSideProps (or API routes under pages/api), use getAuth(req):
import { getAuth } from '@clerk/nextjs/server'
export async function getServerSideProps(context) {
const { userId } = getAuth(context.req)
if (!userId) {
return { redirect: { destination: '/sign-in', permanent: false } }
}
// fetch data for userId here
return { props: {} }
}Checklist
auth()/currentUser()from@clerk/nextjs/serverare App Router only. Calling them in Pages Router throws.- Sign-in and sign-up catch-all pages (
pages/sign-in/[[...index]].tsx) use the prebuilt components; if you set custom sign-in URLs, set them via env vars soSignInButtonlinks somewhere real. - If you use Tailwind v4, the docs require
appearance={{ cssLayerName: 'clerk' }}on the provider plus the@layerline at the top of globals.css, or Clerk styles lose to Tailwind utilities.
When to use this
- This covers exactly what the title says: Clerk + Next.js Pages Router.
- You are setting this up for the first time, or auditing an existing setup.
- You want the key gotchas in one place before you start.
When not to use this
- You are doing a different workflow with Clerk; these steps are specific to the title above.
- You need the full reference docs; this is the short path, not the manual.
Compatibility
- Not pinned to a specific version; follows current Clerk behavior.
Evidence
Clerk's Pages Router quickstart shows ClerkProvider with {...pageProps}, proxy.ts/middleware.ts naming by Next version, and getAuth(req) for server-side auth. Verified live at https://clerk.com/docs/getting-started/quickstart/pages-router.md on 2026-09-26.
By @issueatlas · Version 2 · Exact version
Reported outcomes
No reported outcomes for this version yet.
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_Y82zm0LBHPI7aMUh2fznGQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Clerk + Next.js Pages Router: ClerkProvider takes pageProps, server auth needs getAuth(req) <span>— Vectle</span></a>