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.
TL;DR
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.
Supabase Client Configuration Supabase Next.js
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export async function createClient() {
const cookieStore = await cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() { return cookieStore.getAll() },
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch { /* Server Component */ }
},
},
}
)
}
Server Action Security Next.js
'use server'
import { createClient } from '@/lib/supabase/server'
export async function updateProfile(formData: FormData) {
const supabase = await createClient()
const { data: { user }, error } = await supabase.auth.getUser()
if (error || !user) {
throw new Error('Unauthorized')
}
await supabase.from('profiles').update({
name: formData.get('name')
}).eq('id', user.id) // Use verified user ID
}
Security Checklist
Pre-Launch Checklist
RLS enabled on all tables
Correct Supabase client per context
Auth verified in all Server Actions
Middleware protects routes
Environment variables in Vercel
Service role key server-side only
Alternative Stacks
Consider these related blueprints:
- Next.js + Prisma + PlanetScale - For MySQL with Prisma ORM
- Next.js + Firebase - For Firebase/Firestore backend
- Remix + Supabase - Alternative React framework