Auth

Creating a Supabase client for SSR

Configure your Supabase client to use cookies


To use Server-Side Rendering (SSR) with Supabase, you need to configure your Supabase client to use cookies. The @supabase/ssr package helps you do this for JavaScript/TypeScript applications.

Install

Install the @supabase/supabase-js and @supabase/ssr helper packages:

1
npm install @supabase/supabase-js @supabase/ssr

Set environment variables

Create a .env.local file in the project root directory. In the file, set the project's Supabase URL and Key:

Project URL
Publishable key
Anon key
1
2
NEXT_PUBLIC_SUPABASE_URL=supabase_project_urlNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=supabase_publishable_key

Create a client

You need setup code to configure a Supabase client to use cookies. Once you have the utility code, you can use the createClient utility functions to get a properly configured Supabase client.

Use the browser client in code that runs on the browser, and the server client in code that runs on the server.

Write utility functions to create Supabase clients

To access Supabase from a Next.js app, you need 2 types of Supabase clients:

  1. Client Component client - To access Supabase from Client Components, which run in the browser.
  2. Server Component client - To access Supabase from Server Components, Server Actions, and Route Handlers, which run only on the server.

Since Next.js Server Components can't write cookies, you need middleware to refresh expired Auth tokens and store them.

The middleware is responsible for:

  1. Refreshing the Auth token by calling supabase.auth.getClaims().
  2. Passing the refreshed Auth token to Server Components, so they don't attempt to refresh the same token themselves. This is accomplished with request.cookies.set.
  3. Passing the refreshed Auth token to the browser, so it replaces the old token. This is accomplished with response.cookies.set.

Create a utils/supabase folder at the root of your project, or inside the ./src folder if you are using one, with a file for each type of client. Then copy the utility functions for each client type.

1
2
3
4
5
6
7
8
import { createBrowserClient } from '@supabase/ssr'export function createClient() { return createBrowserClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY! )}
View source

Hook up middleware

The code adds a matcher so the middleware doesn't run on routes that don't access Supabase.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { type NextRequest } from "next/server"import { updateSession } from "@/utils/supabase/middleware"export async function middleware(request: NextRequest) { return await updateSession(request)}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)$).*)", ],}
View source

Congratulations

You're done! To recap, you've successfully:

  • Called Supabase from a Server Action.
  • Called Supabase from a Server Component.
  • Set up a Supabase client utility to call Supabase from a Client Component. You can use this if you need to call Supabase from a Client Component, for example to set up a realtime subscription.
  • Set up middleware to automatically refresh the Supabase Auth session.

You can now use any Supabase features from your client or server code!

Next steps