[{"data":1,"prerenderedAt":177},["ShallowReactive",2],{"blog-blueprints/clerk-nextjs":3},{"id":4,"title":5,"body":6,"category":157,"date":158,"dateModified":158,"description":159,"draft":160,"extension":161,"faq":162,"featured":160,"headerVariant":163,"image":162,"keywords":162,"meta":164,"navigation":165,"ogDescription":166,"ogTitle":162,"path":167,"readTime":168,"schemaOrg":169,"schemaType":170,"seo":171,"sitemap":172,"stem":173,"tags":174,"twitterCard":175,"__hash__":176},"blog/blog/blueprints/clerk-nextjs.md","Clerk + Next.js Integration Security",{"type":7,"value":8,"toc":146},"minimark",[9,20,24,30,35,50,54,63,67,76,85,89,94,97,100,103,106,109,120,134],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure Clerk + Next.js integration,"," you need to: (1) configure middleware with proper route matchers and explicit public routes, (2) use auth() in Server Components and API routes to verify users, (3) always use the verified userId for database operations, (4) add webhook routes to publicRoutes to allow Clerk callbacks, and (5) never trust client-provided user IDs. This blueprint ensures middleware protection and server-side verification work together.",[21,22],"blueprint-meta",{"time":23},"1-2 hours",[25,26,27],"tldr",{},[13,28,29],{},"Clerk's middleware handles route protection automatically. Use auth() in Server Components, currentUser() when you need full user data, and configure publicRoutes properly. The userId from auth() is verified server-side-use it for database queries.",[31,32,34],"h2",{"id":33},"middleware-configuration-clerk-nextjs","Middleware Configuration Clerk Next.js",[36,37,39],"code-block",{"label":38},"middleware.ts",[40,41,46],"pre",{"className":42,"code":44,"language":45},[43],"language-text","import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'\n\nconst isPublicRoute = createRouteMatcher([\n  '/',\n  '/about',\n  '/blog(.*)',\n  '/api/webhooks(.*)',\n])\n\nexport default clerkMiddleware((auth, req) => {\n  if (!isPublicRoute(req)) {\n    auth().protect()\n  }\n})\n\nexport const config = {\n  matcher: ['/((?!.*\\\\..*|_next).*)', '/', '/(api|trpc)(.*)'],\n}\n","text",[47,48,44],"code",{"__ignoreMap":49},"",[31,51,53],{"id":52},"protected-server-component","Protected Server Component",[36,55,57],{"label":56},"app/dashboard/page.tsx",[40,58,61],{"className":59,"code":60,"language":45},[43],"import { auth, currentUser } from '@clerk/nextjs/server'\nimport { redirect } from 'next/navigation'\n\nexport default async function Dashboard() {\n  const { userId } = auth()\n\n  if (!userId) {\n    redirect('/sign-in')\n  }\n\n  // Use userId for database queries\n  const posts = await db.posts.findMany({\n    where: { authorId: userId },\n  })\n\n  const user = await currentUser()\n\n  return (\n    \u003Cdiv>\n      \u003Ch1>Welcome, {user?.firstName}\u003C/h1>\n      {posts.map(post => \u003Cdiv key={post.id}>{post.title}\u003C/div>)}\n    \u003C/div>\n  )\n}\n",[47,62,60],{"__ignoreMap":49},[31,64,66],{"id":65},"protected-api-route","Protected API Route",[36,68,70],{"label":69},"app/api/posts/route.ts",[40,71,74],{"className":72,"code":73,"language":45},[43],"import { auth } from '@clerk/nextjs/server'\nimport { NextResponse } from 'next/server'\n\nexport async function POST(req: Request) {\n  const { userId } = auth()\n\n  if (!userId) {\n    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n  }\n\n  const body = await req.json()\n\n  const post = await db.posts.create({\n    data: {\n      title: body.title,\n      authorId: userId,  // Verified Clerk user ID\n    },\n  })\n\n  return NextResponse.json(post)\n}\n",[47,75,73],{"__ignoreMap":49},[77,78,79],"warning-box",{},[13,80,81,84],{},[16,82,83],{},"Middleware protects routes, not data."," Always verify userId in API routes and Server Components. Use the verified userId for all database operations, never client-provided IDs.",[31,86,88],{"id":87},"security-checklist","Security Checklist",[90,91,93],"h4",{"id":92},"pre-launch-checklist","Pre-Launch Checklist",[13,95,96],{},"Middleware configured with correct matchers",[13,98,99],{},"Public routes explicitly defined",[13,101,102],{},"API routes check auth()",[13,104,105],{},"Database queries use verified userId",[13,107,108],{},"Webhook routes in publicRoutes",[110,111,112,117],"stack-comparison",{},[113,114,116],"h3",{"id":115},"related-integration-stacks","Related Integration Stacks",[13,118,119],{},"Auth0 + Next.js Alternative\nNextAuth + Prisma Self-Hosted\nOAuth Security Patterns",[121,122,123,129],"related-articles",{},[124,125],"related-card",{"description":126,"href":127,"title":128},"Alternative auth","/blog/blueprints/auth0-nextjs","Auth0 + Next.js",[124,130],{"description":131,"href":132,"title":133},"Self-hosted auth","/blog/blueprints/nextauth-prisma","NextAuth + Prisma",[135,136,139,143],"cta-box",{"href":137,"label":138},"/","Start Free Scan",[31,140,142],{"id":141},"check-your-clerk-integration","Check Your Clerk Integration",[13,144,145],{},"Scan for authentication security issues.",{"title":49,"searchDepth":147,"depth":147,"links":148},2,[149,150,151,152,156],{"id":33,"depth":147,"text":34},{"id":52,"depth":147,"text":53},{"id":65,"depth":147,"text":66},{"id":87,"depth":147,"text":88,"children":153},[154],{"id":115,"depth":155,"text":116},3,{"id":141,"depth":147,"text":142},"blueprints","2026-01-30","Security guide for integrating Clerk with Next.js. Configure middleware properly, protect API routes, use auth() in Server Components, and implement secure user management.",false,"md",null,"purple",{},true,"Secure Clerk authentication with Next.js applications.","/blog/blueprints/clerk-nextjs","10 min read","[object Object]","Article",{"title":5,"description":159},{"loc":167},"blog/blueprints/clerk-nextjs",[],"summary_large_image","TfcuSTKyKyqeaJcB85Z7HZe4wx0pFQe4A9M-nBSek64",1775843932621]