[{"data":1,"prerenderedAt":182},["ShallowReactive",2],{"blog-blueprints/nextjs-supabase-vercel":3},{"id":4,"title":5,"body":6,"category":162,"date":163,"dateModified":163,"description":164,"draft":165,"extension":166,"faq":167,"featured":165,"headerVariant":168,"image":167,"keywords":167,"meta":169,"navigation":170,"ogDescription":171,"ogTitle":167,"path":172,"readTime":173,"schemaOrg":174,"schemaType":175,"seo":176,"sitemap":177,"stem":178,"tags":179,"twitterCard":180,"__hash__":181},"blog/blog/blueprints/nextjs-supabase-vercel.md","Next.js + Supabase + Vercel Security Blueprint",{"type":7,"value":8,"toc":152},"minimark",[9,20,23,29,34,49,53,62,66,71,74,77,80,83,86,89,103,140],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure a Next.js + Supabase + Vercel stack,"," you need to: (1) use the correct Supabase client for each context (browser vs server vs middleware), (2) enable RLS on all tables and verify auth in Server Actions using getUser(), (3) protect routes with middleware, (4) configure environment variables in Vercel with proper NEXT_PUBLIC_ prefixes, and (5) never expose the service_role key to clients. This blueprint covers Next.js App Router patterns with Supabase SSR.",[21,22],"blueprint-meta",{},[24,25,26],"tldr",{},[13,27,28],{},"This popular stack requires understanding Next.js App Router's different contexts and Supabase's RLS. Key security tasks: use correct Supabase client for each context (browser, server, middleware), enable RLS on all tables, verify auth in Server Actions with getUser(), configure Vercel environment variables properly, and never expose the service_role key to clients.",[30,31,33],"h2",{"id":32},"supabase-client-configuration-supabase-nextjs","Supabase Client Configuration Supabase Next.js",[35,36,38],"code-block",{"label":37},"lib/supabase/server.ts",[39,40,45],"pre",{"className":41,"code":43,"language":44},[42],"language-text","import { createServerClient } from '@supabase/ssr'\nimport { cookies } from 'next/headers'\n\nexport async function createClient() {\n  const cookieStore = await cookies()\n\n  return createServerClient(\n    process.env.NEXT_PUBLIC_SUPABASE_URL!,\n    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,\n    {\n      cookies: {\n        getAll() { return cookieStore.getAll() },\n        setAll(cookiesToSet) {\n          try {\n            cookiesToSet.forEach(({ name, value, options }) =>\n              cookieStore.set(name, value, options)\n            )\n          } catch { /* Server Component */ }\n        },\n      },\n    }\n  )\n}\n","text",[46,47,43],"code",{"__ignoreMap":48},"",[30,50,52],{"id":51},"server-action-security-nextjs","Server Action Security Next.js",[35,54,56],{"label":55},"Always verify auth in Server Actions",[39,57,60],{"className":58,"code":59,"language":44},[42],"'use server'\n\nimport { createClient } from '@/lib/supabase/server'\n\nexport async function updateProfile(formData: FormData) {\n  const supabase = await createClient()\n  const { data: { user }, error } = await supabase.auth.getUser()\n\n  if (error || !user) {\n    throw new Error('Unauthorized')\n  }\n\n  await supabase.from('profiles').update({\n    name: formData.get('name')\n  }).eq('id', user.id)  // Use verified user ID\n}\n",[46,61,59],{"__ignoreMap":48},[30,63,65],{"id":64},"security-checklist","Security Checklist",[67,68,70],"h4",{"id":69},"pre-launch-checklist","Pre-Launch Checklist",[13,72,73],{},"RLS enabled on all tables",[13,75,76],{},"Correct Supabase client per context",[13,78,79],{},"Auth verified in all Server Actions",[13,81,82],{},"Middleware protects routes",[13,84,85],{},"Environment variables in Vercel",[13,87,88],{},"Service role key server-side only",[90,91,92,98],"related-articles",{},[93,94],"related-card",{"description":95,"href":96,"title":97},"With AI tooling","/blog/blueprints/cursor-nextjs-supabase","Cursor + Next.js + Supabase",[93,99],{"description":100,"href":101,"title":102},"Deep dive","/blog/guides/supabase","Supabase Security Guide",[104,105,106,111,114],"stack-comparison",{},[107,108,110],"h3",{"id":109},"alternative-stacks","Alternative Stacks",[13,112,113],{},"Consider these related blueprints:",[115,116,117,126,133],"ul",{},[118,119,120,125],"li",{},[121,122,124],"a",{"href":123},"/blog/blueprints/nextjs-prisma-planetscale","Next.js + Prisma + PlanetScale"," - For MySQL with Prisma ORM",[118,127,128,132],{},[121,129,131],{"href":130},"/blog/blueprints/nextjs-firebase","Next.js + Firebase"," - For Firebase/Firestore backend",[118,134,135,139],{},[121,136,138],{"href":137},"/blog/blueprints/remix-supabase","Remix + Supabase"," - Alternative React framework",[141,142,145,149],"cta-box",{"href":143,"label":144},"/","Start Free Scan",[30,146,148],{"id":147},"building-with-this-stack","Building with this stack?",[13,150,151],{},"Scan for RLS and auth issues.",{"title":48,"searchDepth":153,"depth":153,"links":154},2,[155,156,157,161],{"id":32,"depth":153,"text":33},{"id":51,"depth":153,"text":52},{"id":64,"depth":153,"text":65,"children":158},[159],{"id":109,"depth":160,"text":110},3,{"id":147,"depth":153,"text":148},"blueprints","2026-02-11","Security guide for Next.js + Supabase + Vercel stack. Configure RLS, secure Server Components and Actions, protect API routes, and deploy safely.",false,"md",null,"purple",{"noindex":170},true,"Complete security configuration for Next.js apps with Supabase on Vercel.","/blog/blueprints/nextjs-supabase-vercel","12 min read","[object Object]","Article",{"title":5,"description":164},{"loc":172},"blog/blueprints/nextjs-supabase-vercel",[],"summary_large_image","LMobwZdmIK5jcWhvJ1ulMrSj2FIAIOOALzpuWDUSP_M",1775843920152]