All TypeScript templates

Next.js + Supabase Auth

Auth flows with Supabase SSR, cookies, and Row Level Security policies.

DevZone Tools2,210 copiesUpdated Apr 2, 2026Next.jsSupabaseTypeScript
# CLAUDE.md — Next.js + Supabase Auth

## Setup

- Use `@supabase/ssr` for the App Router. Do not use the legacy `@supabase/auth-helpers-nextjs`.
- Create three Supabase clients, each in its own file:
  - `lib/supabase/server.ts` — for Server Components, route handlers, and Server Actions
  - `lib/supabase/client.ts` — for Client Components
  - `lib/supabase/middleware.ts` — for the middleware that refreshes session cookies

## Sessions

- Run the middleware on every request. It calls `supabase.auth.getUser()` and refreshes the auth cookies.
- In Server Components, always call `supabase.auth.getUser()` — never `getSession()`. `getSession` reads cookies without revalidating, so it's spoofable.
- Trust `getUser()` only on the server. On the client, treat the user object as a hint and verify with the server before any sensitive UI.

## RLS (Row Level Security)

- Enable RLS on every table. No exceptions.
- Write `policy` blocks for each access pattern: `select`, `insert`, `update`, `delete`. Don't combine them with `using true`.
- Reference `auth.uid()` in policies. Indexes on `user_id` columns are not optional.
- Test policies with the SQL editor's "Run as user" feature before merging.

## Server Actions / Route Handlers

- Auth checks happen at the top of every action. Pattern:
  ```ts
  const { data: { user } } = await supabase.auth.getUser()
  if (!user) return { ok: false, error: 'unauthorized' }
  ```
- Don't pass user IDs from the client. Read them from the authenticated session inside the action.

## Cookies & redirects

- Sign-in / sign-out actions must call `redirect()` after the auth call so cookies flush.
- Use `revalidatePath('/', 'layout')` after sign-in/out to drop cached user-dependent renders.

## Don't

- Don't expose the service-role key to the browser or in any code path that runs in a Client Component.
- Don't disable RLS to "fix" a query — write a policy.
- Don't store auth tokens in `localStorage`. The Supabase SSR client uses cookies.
- Don't use `next/router` for auth redirects in App Router code — use `redirect()` from `next/navigation`.

Other TypeScript templates