Skip to content

fix(auth): keep app mounted across Supabase token refresh - #45

Draft
posthog-eu[bot] wants to merge 1 commit into
mainfrom
posthog-self-driving/fixauth-stop-token-refresh-from-4cc337
Draft

fix(auth): keep app mounted across Supabase token refresh#45
posthog-eu[bot] wants to merge 1 commit into
mainfrom
posthog-self-driving/fixauth-stop-token-refresh-from-4cc337

Conversation

@posthog-eu

@posthog-eu posthog-eu Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Problem

  • Every signed-in user loses the whole app to a blank "Loading..." splash for ~9 s each time their Supabase session refreshes or they tab back in.
  • A token refresh calls invalidate('supabase:auth'), which re-runs the root load. The load rebuilt the browser client and reassigned the supabase.client $state singleton on every run.
  • User state was $derived(new UserState(supabase.client)), so that swap threw away the loaded user and built an empty one — isComplete turned false and (app)/+layout.svelte swapped the entire app for LoadingSplash until four Supabase round trips finished.
  • Impact is unconditional and hides the full page (content, scroll position, unsaved UI state), not one widget. Reach is small today (pre-launch), so this is a pre-launch fix.

Changes

  • Stop the client swap+layout.ts reuses the existing browser client across load re-runs instead of building a new one each time.
  • Make user state a real singleton — replace the module-level $derived(new UserState(...)) with a singleton and a setClient() setter that rebinds a new client while keeping the loaded user data.
  • Latch the splash on first load(app)/+layout.svelte gates LoadingSplash on a first-load flag, so a brief drop in isComplete during a refresh no longer blanks the app.

The three layers are independent, so any one of them alone stops the flash; together they make the state resilient to a client swap.

Also fixed

  • hooks.client.ts imported dev from $app/env, which is not a SvelteKit module. The value comes from $app/environment (already imported on the next line).

Not included

  • The duplicate @lucide/svelte + lucide-svelte dependencies (dev-only ReferenceError: TriangleAlert is not defined on the landing page) are left out. That fix is a dependency migration across ~30 files, unrelated to the token-refresh symptom, and belongs in its own PR.

Testing

  • svelte-check passes on the changed files (remaining errors are pre-existing and come from unset local $env/static/public variables).
  • A live browser reproduction was not possible in the sandbox (no Supabase credentials, authenticated session, or browser). The fix is a reactivity change verified by mechanism analysis and type-checking.

Why

Reported by a user who lost the app to the splash while reading a recipe; the event timeline shows same-URL $pageleave/$pageview pairs across the reported window.


Created with PostHog Desktop from this inbox report.

A token refresh (or a tab refocus) calls invalidate('supabase:auth'),
which re-runs the root load. The load built a new browser client and
reassigned the `supabase.client` $state singleton on every run. Because
the user state was `$derived(new UserState(supabase.client))`, that swap
rebuilt an empty UserState, so `isComplete` turned false and the whole
app hid behind LoadingSplash for several seconds.

Three layers now break that chain:
- +layout.ts reuses the existing browser client instead of rebuilding it.
- UserState is a real singleton; setClient() rebinds a new client and
  keeps the already loaded user data.
- The (app) layout gates the splash on a first-load latch, so a brief
  drop in isComplete no longer blanks the app.

Also fix hooks.client.ts importing `dev` from the non-existent $app/env
module (the value lives in $app/environment).

Generated-By: PostHog Desktop
Task-Id: 4bf014fe-cf36-45a4-95a0-498a8bfd4f70
@vercel

vercel Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cuicuit Ready Ready Preview Aug 23, 2026 11:51am

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants