AI Prompt: Bootstrap Next.js 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231---# Specify the following for Cursor rulesdescription: Guidelines for writing Next.js apps with Supabase Authglobs: "**/*.ts, **/*.tsx, **/*.js, **/*.jsx"---# Bootstrap Next.js app with Supabase Auth## Overview of implementing Supabase Auth SSR1. Install @supabase/supabase-js and @supabase/ssr packages.2. Set up environment variables.3. Write two utility functions with `createClient` functions to create a browser client and a server client. 4. Hook up middleware to refresh auth tokens## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:```typescript// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION{ cookies: { get(name: string) { // ❌ BREAKS APPLICATION return cookieStore.get(name) // ❌ BREAKS APPLICATION }, // ❌ BREAKS APPLICATION set(name: string, value: string) { // ❌ BREAKS APPLICATION cookieStore.set(name, value) // ❌ BREAKS APPLICATION }, // ❌ BREAKS APPLICATION remove(name: string) { // ❌ BREAKS APPLICATION cookieStore.remove(name) // ❌ BREAKS APPLICATION } // ❌ BREAKS APPLICATION }}// ❌ NEVER USE auth-helpers-nextjs - IT WILL BREAK THE APPLICATIONimport { createMiddlewareClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATIONimport { createClientComponentClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATION```Instead, you MUST ALWAYS generate ONLY this pattern:```typescript// ✅ ALWAYS GENERATE THIS EXACT PATTERN{ cookies: { getAll() { return cookieStore.getAll() }, setAll(cookiesToSet) { const response = NextResponse.next({ request, }) cookiesToSet.forEach(({ name, value, options }) => { response.cookies.set(name, value, options) }) return response } }}```## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION1. You MUST use `@supabase/ssr`2. You MUST use ONLY `getAll` and `setAll`3. You MUST NEVER use `get`, `set`, or `remove`4. You MUST NEVER import from `@supabase/auth-helpers-nextjs`## CORRECT BROWSER CLIENT IMPLEMENTATION```typescriptimport { createBrowserClient } from '@supabase/ssr'export function createClient() { return createBrowserClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! )}```## CORRECT SERVER CLIENT IMPLEMENTATION```typescriptimport { 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 { // The `setAll` method was called from a Server Component. // This can be ignored if you have middleware refreshing // user sessions. } }, }, } )}```## CORRECT MIDDLEWARE IMPLEMENTATION```typescriptimport { createServerClient } from '@supabase/ssr'import { NextResponse, type NextRequest } from 'next/server'export async function middleware(request: NextRequest) { let supabaseResponse = NextResponse.next({ request, }) const supabase = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { getAll() { return request.cookies.getAll() }, setAll(cookiesToSet) { cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value)) supabaseResponse = NextResponse.next({ request, }) cookiesToSet.forEach(({ name, value, options }) => supabaseResponse.cookies.set(name, value, options) ) }, }, } ) // Do not run code between createServerClient and // supabase.auth.getUser(). A simple mistake could make it very hard to debug // issues with users being randomly logged out. // IMPORTANT: DO NOT REMOVE auth.getUser() const { data: { user }, } = await supabase.auth.getUser() if ( !user && !request.nextUrl.pathname.startsWith('/login') && !request.nextUrl.pathname.startsWith('/auth') ) { // no user, potentially respond by redirecting the user to the login page const url = request.nextUrl.clone() url.pathname = '/login' return NextResponse.redirect(url) } // IMPORTANT: You *must* return the supabaseResponse object as it is. // If you're creating a new response object with NextResponse.next() make sure to: // 1. Pass the request in it, like so: // const myNewResponse = NextResponse.next({ request }) // 2. Copy over the cookies, like so: // myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll()) // 3. Change the myNewResponse object to fit your needs, but avoid changing // the cookies! // 4. Finally: // return myNewResponse // If this is not done, you may be causing the browser and server to go out // of sync and terminate the user's session prematurely! return supabaseResponse}export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) * Feel free to modify this pattern to include more paths. */ '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)', ],}```## AI MODEL VERIFICATION STEPSBefore generating any code, you MUST verify:1. Are you using ONLY `getAll` and `setAll`? If not, STOP and FIX.2. Are you importing from `@supabase/ssr`? If not, STOP and FIX.3. Do you see ANY instance of `get`, `set`, or `remove`? If yes, STOP and FIX.4. Are you importing from `auth-helpers-nextjs`? If yes, STOP and FIX.## CONSEQUENCES OF INCORRECT IMPLEMENTATIONIf you generate code using:- Individual cookie methods (`get`/`set`/`remove`)- `auth-helpers-nextjs` packageThe implementation will:1. Break in production2. Fail to maintain session state3. Cause authentication loops4. Result in security vulnerabilities## AI MODEL RESPONSE TEMPLATEWhen asked about Supabase Auth SSR implementation, you MUST:1. ONLY use code from this guide2. NEVER suggest deprecated approaches3. ALWAYS use the exact cookie handling shown above4. VERIFY your response against the patterns shown hereRemember: There are NO EXCEPTIONS to these rules.