Getting Started

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
---# 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.