From 9e99ed927012c554bafb6f63bd16810997d12615 Mon Sep 17 00:00:00 2001 From: SilkePilon Date: Sat, 8 Aug 2026 17:02:50 +0200 Subject: [PATCH] fix: don't flash logged-out UI while the user is still loading Web auth is cookie based, so the client can't tell synchronously whether you're signed in. `UserService.user` starts as `undefined` and only gets populated once `GET /api/user` comes back, which meant `undefined` stood for both "still fetching" and "logged out". Consumers read it as "logged out" on the first frame. The profile page showed "It looks like you're not logged in" until the fetch resolved, and the header flashed the Log in / Sign up buttons. The rules and reviews pages had it worse: they redirected you to home before the fetch had a chance to finish, so refreshing either page while signed in bounced you out. `UserService` now exposes a `loaded` store that flips once the initial fetch settles, and the pages wait for it before rendering logged-out UI or redirecting. Conditions are ordered so `$user` is read before `$userLoaded`. Svelte only subscribes to a store when the expression reading it actually runs, so short circuiting on `$userLoaded` first would leave `$user` unsubscribed, the fetch never started, and the page stuck loading. Co-Authored-By: Claude Opus 5 (1M context) --- apps/web/src/lib/components/HeaderAuthSection.svelte | 9 ++++++++- apps/web/src/lib/user/userService.ts | 8 ++++++++ .../[ownerSlug]/[projectSlug]/reviews/+page.svelte | 3 ++- .../src/routes/(app)/[ownerSlug]/rules/+page.svelte | 3 ++- .../organizations/invite/[slug]/[code]/+page.svelte | 7 ++++++- apps/web/src/routes/(app)/profile/+page.svelte | 10 +++++++++- 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/apps/web/src/lib/components/HeaderAuthSection.svelte b/apps/web/src/lib/components/HeaderAuthSection.svelte index 70bed435e5e..00d6d700187 100644 --- a/apps/web/src/lib/components/HeaderAuthSection.svelte +++ b/apps/web/src/lib/components/HeaderAuthSection.svelte @@ -14,10 +14,13 @@ const userService = inject(USER_SERVICE); const user = $derived(userService.user); + const userLoaded = $derived(userService.loaded); const routes = inject(WEB_ROUTES_SERVICE); -{#if $user && !hideIfUserAuthenticated} +{#if !$user && !$userLoaded} +
+{:else if $user && !hideIfUserAuthenticated} {:else if !$user}