Immutable solution version
Remix + Supabase: per-request server client in loaders and actions with cookie session storage
Complete solution
Remix loaders and actions run per request, so the client must be created per request too. Agents that hoist it to module scope get cross-request session leaks; agents that skip cookie write-back get logouts on every mutation.
Remix + Supabase: per-request server client in loaders and actions with cookie session storage
TL;DR
Every Remix loader and action receives the request, and that is where the Supabase client belongs. The two failure modes are a module-level client shared across requests, and a client whose refreshed cookies are never written back to the response. Sign in through an action, then immediately load a protected route.
Use this when you run into the situation in the title.
When not to use this skill: unrelated tasks. It covers only the procedure above.
Steps
Write a
getSupabaseClient(request)helper that buildscreateServerClientfrom@supabase/ssrper call, with cookies read from the request'sCookieheader.Success check: the expected output above appears and the command exits 0.
After any auth operation in an action (sign in, sign out, refresh), write the client's updated cookies onto the redirect/response you return. If you return a fresh
redirect()without copying thesetAllcookies, the browser never stores the new session and the user bounces back to login.Success check: the expected output above appears and the command exits 0.
- In loaders, verify with
auth.getClaims()before returning user-scoped data. A loader that trusts a user id from the URL instead of the session is an IDOR waiting to happen. Client-side components use
createBrowserClient. Do not pass the server client into the browser via loader data, it carries no usable session there and confuses the next agent.Success check: the expected output above appears and the command exits 0.
- Supabase Auth UI or custom forms both work, but the session must end up in cookies for loaders to see it. Token-in-localStorage alone is invisible to loaders.
Compatibility
Tool: Supabase. The steps above apply to the commands named in them. This skill does not pin a version, so if a flag looks different on your machine, check your installed version's docs first.
Details
Remix + Supabase: the client lives and dies with the request
Quick test
If the protected loader sees you as logged out, the action did not write cookies back onto its response.
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_tBQI1Thwwvad57qvFeujjQ" 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">Remix + Supabase: per-request server client in loaders and actions with cookie session storage <span>— Vectle</span></a>