Getting Started

API 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


_108
# Bootstrap Next.js app with Supabase Auth
_108
_108
Create a Next.js app that uses App Router with Supabase Auth.
_108
_108
Follow Supabase's guidelines for using the `@supabase/ssr` package and Server-Side Auth. Specifically, there should be:
_108
_108
- A utility function to create a client on the client side
_108
- A utility function create a client on the server side, using the Next.js `cookies` API to access the cookies. Use the latest version of the API, where `cookies` must be awaited.
_108
- A utility function to handle refreshing the user session in middleware.
_108
_108
## Working with cookies
_108
_108
Use the latest version of `@supabase/ssr`, where cookie options are defined with the `getAll` and `setAll` functions, like so:
_108
_108
```
_108
const supabase = createServerClient(
_108
process.env.NEXT_PUBLIC_SUPABASE_URL!,
_108
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
_108
{
_108
cookies: {
_108
getAll() {
_108
return request.cookies.getAll()
_108
},
_108
setAll(cookiesToSet) {
_108
cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
_108
supabaseResponse = NextResponse.next({
_108
request,
_108
})
_108
cookiesToSet.forEach(({ name, value, options }) =>
_108
supabaseResponse.cookies.set(name, value, options)
_108
)
_108
},
_108
},
_108
}
_108
)
_108
```
_108
_108
No other cookie options should be provided.
_108
_108
## Middleware
_108
_108
The middleware should use the following `updateSession` function:
_108
_108
```
_108
import { createServerClient } from '@supabase/ssr'
_108
import { NextResponse, type NextRequest } from 'next/server'
_108
_108
export async function updateSession(request: NextRequest) {
_108
let supabaseResponse = NextResponse.next({
_108
request,
_108
})
_108
_108
const supabase = createServerClient(
_108
process.env.NEXT_PUBLIC_SUPABASE_URL!,
_108
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
_108
{
_108
cookies: {
_108
getAll() {
_108
return request.cookies.getAll()
_108
},
_108
setAll(cookiesToSet) {
_108
cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
_108
supabaseResponse = NextResponse.next({
_108
request,
_108
})
_108
cookiesToSet.forEach(({ name, value, options }) =>
_108
supabaseResponse.cookies.set(name, value, options)
_108
)
_108
},
_108
},
_108
}
_108
)
_108
_108
// IMPORTANT: Avoid writing any logic between createServerClient and
_108
// supabase.auth.getUser(). A simple mistake could make it very hard to debug
_108
// issues with users being randomly logged out.
_108
_108
const {
_108
data: { user },
_108
} = await supabase.auth.getUser()
_108
_108
if (
_108
!user &&
_108
!request.nextUrl.pathname.startsWith('/login') &&
_108
!request.nextUrl.pathname.startsWith('/auth')
_108
) {
_108
// no user, potentially respond by redirecting the user to the login page
_108
const url = request.nextUrl.clone()
_108
url.pathname = '/login'
_108
return NextResponse.redirect(url)
_108
}
_108
_108
// IMPORTANT: You *must* return the supabaseResponse object as it is. If you're
_108
// creating a new response object with NextResponse.next() make sure to:
_108
// 1. Pass the request in it, like so:
_108
// const myNewResponse = NextResponse.next({ request })
_108
// 2. Copy over the cookies, like so:
_108
// myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
_108
// 3. Change the myNewResponse object to fit your needs, but avoid changing
_108
// the cookies!
_108
// 4. Finally:
_108
// return myNewResponse
_108
// If this is not done, you may be causing the browser and server to go out
_108
// of sync and terminate the user's session prematurely!
_108
_108
return supabaseResponse
_108
}
_108
```