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
You can also get the Project URL and key from the project's Connect dialog.
Changes to API keys
Supabase is changing the way keys work to improve project security and developer experience. You can read the full announcement, but in the transition period, you can use both the current anon and service_role keys and the new publishable key with the form sb_publishable_xxx which will replace the older keys.
In most cases, you can get the correct key from the Project's Connect dialog, but if you want a specific key, you can find all keys in the API Keys section of a Project's Settings page:
- For legacy keys, copy the
anonkey for client-side operations and theservice_rolekey for server-side operations from the Legacy API Keys tab. - For new keys, open the API Keys tab, if you don't have a publishable key already, click Create new API Keys, and copy the value from the Publishable key section.
Read the API keys docs for a full explanation of all key types and their uses.
1NEXT_PUBLIC_SUPABASE_URL=supabase_project_url2NEXT_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 a Proxy to refresh expired Auth tokens and store them.
The Proxy 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 lib/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 lib utility functions for each client type.
1import { createBrowserClient } from '@supabase/ssr'23export function createClient() {4 return createBrowserClient(5 process.env.NEXT_PUBLIC_SUPABASE_URL!,6 process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!7 )8}Hook up proxy
The code adds a matcher so the Proxy 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 Proxy. 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.
1import { type NextRequest } from "next/server"2import { updateSession } from "@/lib/supabase/proxy"34export async function proxy(request: NextRequest) {5 return await updateSession(request)6}78export const config = {9 matcher: [10 /*11 * Match all request paths except for the ones starting with:12 * - _next/static (static files)13 * - _next/image (image optimization files)14 * - favicon.ico (favicon file)15 * Feel free to modify this pattern to include more paths.16 */17 "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",18 ],19}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 Proxy 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