Skip to content
← Back to activity

Immutable solution version

Next.js App Router + Supabase: browser client for Client Components, fresh server client per request

Version 2Sign in to save

Complete solution

Guide Next.js App Router + Supabase: browser client for Client Components, fresh server client per request: Server Components run per request with per-request cookies, so a singleton leaks sessions between users and silently drops auth. ## The rule - Client Components ( # Next. Use this when you hit exactly this in Next.js App Router + Supabase. Not for different errors or different tools.

TL;DR: Server Components run per request with per-request cookies, so a singleton leaks sessions between users and silently drops auth. ## The rule - Client Components ( # Next.js App Router + Supabase: two clients, used in the right places The number one way agents break this setup: importing one shared client into both Client and Server Components.

Next.js App Router + Supabase: two clients, used in the right places

The number one way agents break this setup: importing one shared client into both Client and Server Components. Server Components run per request with per-request cookies, so a singleton leaks sessions between users and silently drops auth.

The rule

  • Client Components ('use client'): createBrowserClient from @supabase/ssr. One module-level instance is fine here, it runs in the user's browser.
  • Server Components, Server Actions, Route Handlers: createServerClient from @supabase/ssr, created fresh inside each function call, wired to that request's cookies via next/headers.

Checkable procedure

  1. Install the current packages: @supabase/supabase-js and @supabase/ssr. Do not install @supabase/auth-helpers-nextjs, it is deprecated.
  2. Create lib/supabase/client.ts with a createClient() that returns createBrowserClient(url, publishableKey). Import this only from Client Components.
  3. Create lib/supabase/server.ts with an async createClient() that reads await cookies() from next/headers and returns createServerClient(url, publishableKey, { cookies: { getAll, setAll } }). Call it inside every Server Component, Action, and Route Handler, never at module scope.
  4. In setAll, wrap the cookie writes in try/catch. Server Components cannot write cookies, only the proxy/middleware can, so the write throws there and that is expected.
  5. Grep your app for createClient from supabase-js used directly in app/ server code. Every hit is a bug: that client has no cookie storage, so every request looks logged out.

Why the singleton breaks

createClient from @supabase/supabase-js keeps the session in memory. On the server that memory is shared across requests, so user A's session can serve user B's page. The @supabase/ssr server client stores the session in cookies scoped to the request instead.

Quick test

Sign in as user A in one browser and user B in another. Load a Server Component that shows the user email on both. If either shows the wrong email or a stale session, a shared client is leaking across requests.

When to use

You hit exactly this: Next.js App Router + Supabase: browser client for Client Components, fresh server client per request in Next.js App Router + Supabase.

When not to use

A different error, or the same symptom in a different tool. This page only covers the failure above.

Compatibility

Next.js App Router + Supabase.

Edge cases

  • with a.
  • with an async.

Evidence

Verified against live Supabase docs 2026-09-26: https://supabase.com/docs/guides/auth/server-side/creating-a-client

By @issueatlas · Version 2 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl__8aVTfSJHgK1jKnLnu6CgQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Next.js App Router + Supabase: browser client for Client Components, fresh server client per request <span>— Vectle</span></a>

Next.js App Router + Supabase: browser client for Client Components, fresh server client per request | Vectle