AI Prompt: Bootstrap Next.js v16 app with Supabase Auth
How to use#
Copy the prompt to a file in your repo.
Use the "include file" feature from your AI tool to include the prompt when chatting with your AI assistant. For example, with GitHub Copilot, use #<filename>, in Cursor, use @Files, and in Zed, use /file.
Prompt#
1# Bootstrap Next.js v16 app with Supabase Auth23## Overview of implementing Supabase Auth SSR451. Install @supabase/supabase-js and @supabase/ssr packages.62. Set up environment variables.73. Write two utility functions with `createClient` functions to create a browser client and a server client.84. Hook up Proxy to refresh auth tokens910## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨1112As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:1314```typescript15// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION16{17 cookies: {18 get(name: string) { // ❌ BREAKS APPLICATION19 return cookieStore.get(name) // ❌ BREAKS APPLICATION20 }, // ❌ BREAKS APPLICATION21 set(name: string, value: string) { // ❌ BREAKS APPLICATION22 cookieStore.set(name, value) // ❌ BREAKS APPLICATION23 }, // ❌ BREAKS APPLICATION24 remove(name: string) { // ❌ BREAKS APPLICATION25 cookieStore.remove(name) // ❌ BREAKS APPLICATION26 } // ❌ BREAKS APPLICATION27 }28}2930// ❌ NEVER USE auth-helpers-nextjs - IT WILL BREAK THE APPLICATION31import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATION32import { createClientComponentClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATION33```3435Instead, you MUST ALWAYS generate ONLY this pattern:3637```typescript38// ✅ ALWAYS GENERATE THIS EXACT PATTERN39{40 cookies: {41 getAll() {42 return cookieStore.getAll()43 },44 setAll(cookiesToSet, headers) {45 const response = NextResponse.next({46 request,47 })4849 cookiesToSet.forEach(({ name, value, options }) => {50 response.cookies.set(name, value, options)51 })52 Object.entries(headers).forEach(([key, value]) =>53 response.headers.set(key, value)54 )5556 return response57 }58 }59}60```6162## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION63641. You MUST use `@supabase/ssr`652. You MUST use ONLY `getAll` and `setAll`663. You MUST NEVER use `get`, `set`, or `remove`674. You MUST NEVER import from `@supabase/auth-helpers-nextjs`6869## CORRECT BROWSER CLIENT IMPLEMENTATION7071```typescript72import { createBrowserClient } from '@supabase/ssr'7374export function createClient() {75 return createBrowserClient(76 process.env.NEXT_PUBLIC_SUPABASE_URL!,77 process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!78 )79}80```8182## CORRECT SERVER CLIENT IMPLEMENTATION8384```typescript85import { createServerClient } from '@supabase/ssr'86import { cookies } from 'next/headers'8788export async function createClient() {89 const cookieStore = await cookies()9091 return createServerClient(92 process.env.NEXT_PUBLIC_SUPABASE_URL!,93 process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,94 {95 cookies: {96 getAll() {97 return cookieStore.getAll()98 },99 setAll(cookiesToSet, _headers) {100 try {101 cookiesToSet.forEach(({ name, value, options }) =>102 cookieStore.set(name, value, options)103 )104 } catch {105 // The `setAll` method was called from a Server Component.106 // This can be ignored if you have proxy refreshing107 // user sessions.108 }109 },110 },111 }112 )113}114```115116## CORRECT PROXY IMPLEMENTATION117118```typescript119import { createServerClient } from '@supabase/ssr'120import { NextResponse, type NextRequest } from 'next/server'121122export async function proxy(request: NextRequest) {123 let supabaseResponse = NextResponse.next({124 request,125 })126127 const supabase = createServerClient(128 process.env.NEXT_PUBLIC_SUPABASE_URL!,129 process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,130 {131 cookies: {132 getAll() {133 return request.cookies.getAll()134 },135 setAll(cookiesToSet, headers) {136 cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value))137 supabaseResponse = NextResponse.next({138 request,139 })140 cookiesToSet.forEach(({ name, value, options }) =>141 supabaseResponse.cookies.set(name, value, options)142 )143 Object.entries(headers).forEach(([key, value]) =>144 supabaseResponse.headers.set(key, value)145 )146 },147 },148 }149 )150151 // Do not run code between createServerClient and152 // supabase.auth.getUser(). A simple mistake could make it very hard to debug153 // issues with users being randomly logged out.154155 // IMPORTANT: DO NOT REMOVE auth.getUser()156157 const {158 data: { user },159 } = await supabase.auth.getUser()160161 if (162 !user &&163 !request.nextUrl.pathname.startsWith('/login') &&164 !request.nextUrl.pathname.startsWith('/auth')165 ) {166 // no user, potentially respond by redirecting the user to the login page167 const url = request.nextUrl.clone()168 url.pathname = '/login'169 return NextResponse.redirect(url)170 }171172 // IMPORTANT: You *must* return the supabaseResponse object as it is.173 // If you're creating a new response object with NextResponse.next() make sure to:174 // 1. Pass the request in it, like so:175 // const myNewResponse = NextResponse.next({ request })176 // 2. Copy over the cookies, like so:177 // myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())178 // 3. Change the myNewResponse object to fit your needs, but avoid changing179 // the cookies!180 // 4. Finally:181 // return myNewResponse182 // If this is not done, you may be causing the browser and server to go out183 // of sync and terminate the user's session prematurely!184185 return supabaseResponse186}187188export const config = {189 matcher: [190 /*191 * Match all request paths except for the ones starting with:192 * - _next/static (static files)193 * - _next/image (image optimization files)194 * - favicon.ico (favicon file)195 * Feel free to modify this pattern to include more paths.196 */197 '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',198 ],199}200```201202## AI MODEL VERIFICATION STEPS203204Before generating any code, you MUST verify:2052061. Are you using ONLY `getAll` and `setAll`? If not, STOP and FIX.2072. Are you importing from `@supabase/ssr`? If not, STOP and FIX.2083. Do you see ANY instance of `get`, `set`, or `remove`? If yes, STOP and FIX.2094. Are you importing from `auth-helpers-nextjs`? If yes, STOP and FIX.210211## CONSEQUENCES OF INCORRECT IMPLEMENTATION212213If you generate code using:214215- Individual cookie methods (`get`/`set`/`remove`)216- `auth-helpers-nextjs` package217218The implementation will:2192201. Break in production2212. Fail to maintain session state2223. Cause authentication loops2234. Result in security vulnerabilities224225## AI MODEL RESPONSE TEMPLATE226227When asked about Supabase Auth SSR implementation, you MUST:2282291. ONLY use code from this guide2302. NEVER suggest deprecated approaches2313. ALWAYS use the exact cookie handling shown above2324. VERIFY your response against the patterns shown here233234Remember: There are NO EXCEPTIONS to these rules.