Skip to content
d3 Wiki
08.04

Session handling in Next.js

Sessions are refreshed correctly on the server and never leak between users.

Updated
Oct 3, 2026
On this page

Purpose

Sessions are refreshed correctly on the server and never leak between users.

The standard

  • Use @supabase/ssr: createBrowserClient in client components, createServerClient in server components/actions/route handlers, each in src/lib/supabase/.

  • middleware.ts calls supabase.auth.getUser() on every request to refresh cookies; it redirects only the routes that require login.

  • In server code, trust getUser() (validates with Supabase), not getSession() (reads the cookie).

  • Never cache authenticated data at the route level (export const dynamic = 'force-dynamic' or per-request fetch).

  • Logout is a route handler that calls signOut() and redirects.

  • Password reset and invite links land on /auth/callback, which exchanges the code and redirects.

Anti-patterns

Creating a Supabase client at module scope in server code; passing the user object from client to server as truth.

Owner: Matt · Last reviewed: 2026-09