Supabase Auth with the Next.js App Router
The Next.js Auth Helpers package configures Supabase Auth to store the user's session
in a cookie
, rather than localStorage
. This makes it available across the client and server of the App Router - Client Components, Server Components, Server Actions, Route Handlers and Middleware. The session
is automatically sent along with any requests to Supabase.
note
If you are using the pages
directory, check out Auth Helpers in Next.js Pages Directory.
Automatic Configuration (recommended)#
Use the create-next-app
command and the with-supabase
template to automate the configuration of cookie-based auth with the Next.js Auth Helpers.
This creates a new Next.js app configured with:
Declare Environment Variables#
Retrieve your project's URL and anon key from your API settings, and create a .env.local
file with the following environment variables:
Run Next.js App#
Run the development server and navigate to http://localhost:3000.
Manual Configuration#
Install Next.js Auth Helpers library#
Declare Environment Variables#
Retrieve your project's URL and anon key from your API settings, and create a .env.local
file with the following environment variables:
Managing session with Middleware#
When using the Supabase client on the server, you must perform extra steps to ensure the user's auth session remains active. Since the user's session is tracked in a cookie, we need to read this cookie and update it if necessary.
Next.js Server Components allow you to read a cookie but not write back to it. Middleware on the other hand allow you to both read and write to cookies.
Next.js Middleware runs immediately before each route is rendered. We'll use Middleware to refresh the user's session before loading Server Component routes.
Create a new middleware.js
file in the root of your project and populate with the following:
note
The getSession
function must be called for any Server Component routes that use a Supabase client.
Managing sign-in with Code Exchange#
The Next.js Auth Helpers are configured to use the server-side auth flow to sign users into your application. This requires you to setup a Code Exchange
route, to exchange an auth code
for the user's session
, which is set as a cookie for future requests made to Supabase.
To make this work with Next.js, we create a callback Route Handler that performs this exchange:
Create a new file at app/auth/callback/route.js
and populate with the following:
Authentication#
Authentication can be initiated client or server-side. All of the supabase-js authentication strategies are supported with the Auth Helpers client.
note
The authentication flow requires the Code Exchange Route to exchange a code
for the user's session
.
Client-side#
Client Components can be used to trigger the authentication process from event handlers.
Server-side#
The combination of Server Components and Route Handlers can be used to trigger the authentication process from form submissions.
Sign Up Route
note
Returning a 301
status redirects from a POST to a GET route
Login Route
note
Returning a 301
status redirects from a POST to a GET route
Logout Route
Login Page
Creating a Supabase Client#
There are 5 ways to access the Supabase client with the Next.js Auth Helpers:
- Client Components —
createClientComponentClient
in Client Components - Server Components —
createServerComponentClient
in Server Components - Server Actions —
createServerActionClient
in Server Actions - Route Handlers —
createRouteHandlerClient
in Route Handlers - Middleware —
createMiddlewareClient
in Middleware
This allows for the Supabase client to be easily instantiated in the correct context. All you need to change is the context in the middle create[ClientComponent|ServerComponent|ServerAction|RouteHandler|Middleware]Client
and the Auth Helpers will take care of the rest.
Client Components#
Client Components allow the use of client-side hooks - such as useEffect
and useState
. They can be used to request data from Supabase client-side, and subscribe to realtime events.
info
Check out the Next.js auth example repo for more examples, including realtime subscriptions.
Singleton
The createClientComponentClient
function implements a Singleton pattern by default, meaning that all invocations will return the same Supabase client instance. If you need multiple Supabase instances across Client Components, you can pass an additional configuration option { isSingleton: false }
to get a new client every time this function is called.
_10const supabase = createClientComponentClient({ isSingleton: false })
Server Components#
Server Components allow for asynchronous data to be fetched server-side.
note
In order to use Supabase in Server Components, you need to have implemented the Middleware steps above.
info
Check out the Next.js auth example repo for more examples, including redirecting unauthenticated users - protected pages.
Server Actions#
Server Actions allow mutations to be performed server-side.
note
Next.js Server Actions are currently in alpha
so may change without notice.
Route Handlers#
Route Handlers replace API Routes and allow for logic to be performed server-side. They can respond to GET
, POST
, PUT
, PATCH
, DELETE
, HEAD
, and OPTIONS
requests.
Middleware#
See refreshing session example above.
Edge Runtime#
The Next.js Edge Runtime allows you to host Server Components and Route Handlers from Edge nodes, serving the routes as close as possible to your user's location.
A route can be configured to use the Edge Runtime by exporting a runtime
variable set to edge
. Additionally, the cookies()
function must be called from the Edge route, before creating a Supabase Client.
Server Components
Route Handlers
Static Routes#
Server Components and Route Handlers are static by default - data is fetched once at build time and the value is cached. Since the request to Supabase now happens at build time, there is no user, session or cookie to pass along with the request to Supabase. Therefore, the createClient
function from supabase-js
can be used to fetch data for static routes.
Server Components
Route Handlers
More examples#
- Build a Twitter Clone with the Next.js App Router and Supabase - free egghead course
- Cookie-based Auth and the Next.js 13 App Router (free course)
- Full App Router example
- Realtime Subscriptions
- Protected Routes
- Conditional Rendering in Client Components with SSR
Migration Guide#
Migrating to v0.7.X#
PKCE Auth Flow
PKCE is the new server-side auth flow implemented by the Next.js Auth Helpers. It requires a new Route Handler for /auth/callback
that exchanges an auth code
for the user's session
.
Check the Code Exchange Route steps above to implement this Route Handler.
Authentication
For authentication methods that have a redirectTo
or emailRedirectTo
, this must be set to this new code exchange Route Handler - /auth/callback
. This is an example with the signUp
function:
_10supabase.auth.signUp({_10 email: 'jon@example.com',_10 password: 'sup3rs3cur3',_10 options: {_10 emailRedirectTo: 'http://localhost:3000/auth/callback',_10 },_10})
Deprecated Functions
With v0.7.x of the Next.js Auth Helpers a new naming convention has been implemented for createClient functions. The createMiddlewareSupabaseClient
, createBrowserSupabaseClient
, createServerComponentSupabaseClient
and createRouteHandlerSupabaseClient
functions have been marked as deprecated, and will be removed in a future version of the Auth Helpers.
createMiddlewareSupabaseClient
has been replaced withcreateMiddlewareClient
createBrowserSupabaseClient
has been replaced withcreateClientComponentClient
createServerComponentSupabaseClient
has been replaced withcreateServerComponentClient
createRouteHandlerSupabaseClient
has been replaced withcreateRouteHandlerClient
createClientComponentClient returns singleton
You no longer need to implement logic to ensure there is only a single instance of the Supabase Client shared across all Client Components - this is now the default and handled by the createClientComponentClient
function. Call it as many times as you want!
_10"use client";_10_10import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";_10_10export default function() {_10 const supabase = createClientComponentClient();_10 return ..._10}
For an example of creating multiple Supabase clients, check Singleton section above.