cursor.directory
--- description: Guidelines for writing Next.js apps with Supabase Auth globs: "**/*.ts, **/*.tsx, **/*.js, **/*.jsx" --- # Bootstrap Next.js app with Supabase Auth ## Overview of implementing Supabase Auth SSR 1. 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 APPLICATION import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs' // ❌ BREAKS APPLICATION import { 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 GENERATION 1. 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 ```typescript import { 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 ```typescript 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 { // The `setAll` method was called from a Server Component. // This can be ignored if you have middleware refreshing // user sessions. } }, }, } ) } ``` ## CORRECT MIDDLEWARE IMPLEMENTATION ```typescript import { 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 STEPS Before 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 IMPLEMENTATION If you generate code using: - Individual cookie methods (`get`/`set`/`remove`) - `auth-helpers-nextjs` package The implementation will: 1. Break in production 2. Fail to maintain session state 3. Cause authentication loops 4. Result in security vulnerabilities ## AI MODEL RESPONSE TEMPLATE When asked about Supabase Auth SSR implementation, you MUST: 1. ONLY use code from this guide 2. NEVER suggest deprecated approaches 3. ALWAYS use the exact cookie handling shown above 4. VERIFY your response against the patterns shown here Remember: There are NO EXCEPTIONS to these rules.

Supabase