Client and server needs to stay in sync to avoid auth state errors. SC can't set cookies/headers so we use middleware. Also, server can't know about auth state changes on client so we track this as well.
utils/supabase-browser
- Used inside client components
utils/supabase-server
- Used inside server components
app/middleware.ts
- Server components can't set cookies or headers yet (read-only, see docs). So they can't renew
access_token
that's needed for Supabase client. - Middleware runs before server components and can write both cookies and headers. Middleware refreshes user's session with
getSession()
call soaccess_token
in Supabase client remains up-to-date. - Every server component route that uses Supabase client must be added to middleware's
matcher
array.
- Server components can't set cookies or headers yet (read-only, see docs). So they can't renew
components/supabase-listener
- Client component that runs
onAuthStateChange()
every time there's auth state change (e.g login, logout user events). - Function checks server's
access_token
against the new instance obtained from browser client (supabase-browser
). If server !== client, function runsrouter.refresh()
to reload active route.
- Client component that runs
app/layout
- Fetches server-side session (
supabase-server
) and passes it intosupabase-listener
- Fetches server-side session (