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:
1npm install @supabase/supabase-js @supabase/ssrSet 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
12NEXT_PUBLIC_SUPABASE_URL=supabase_project_urlNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=supabase_publishable_keyCreate 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:
- Client Component client - To access Supabase from Client Components, which run in the browser.
- 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:
- Refreshing the Auth token by calling
supabase.auth.getClaims(). - 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. - 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.
12345678import { createBrowserClient } from '@supabase/ssr'export function createClient() { return createBrowserClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY! )}Hook up middleware
The code adds a matcher so the middleware doesn't run on routes that don't access Supabase.
Be careful when protecting pages. The server gets the user session from the cookies, which can be spoofed by anyone.
Always use supabase.auth.getClaims() to protect pages and user data.
Never trust supabase.auth.getSession() inside server code such as middleware. It isn't guaranteed to revalidate the Auth token.
It's safe to trust getClaims() because it validates the JWT signature against the project's published public keys every time.
12345678910111213141516171819import { 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)$).*)", ],}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
- Implement Authentication using Email and Password
- Implement Authentication using OAuth
- Learn more about SSR