Skip to content

[FE-03] Fix race condition in Zustand auth hydration causing flash of protected content #271

Description

@Leothosine

Problem

frontend/providers/ProtectedRoute.tsx:19 uses a hardcoded 100ms setTimeout to wait for Zustand's persist middleware to rehydrate from localStorage. On slower devices the auth check at line 24 executes before hydration completes. The result is that unauthenticated users briefly see protected admin content before being redirected.

Proposed Solution

  1. In the auth Zustand store, add a _hasHydrated: boolean field (default: false)
  2. Use Zustand's onRehydrateStorage callback to set _hasHydrated = true once persistence finishes
  3. Create a useAuthRehydrated() hook that subscribes to _hasHydrated
  4. Update ProtectedRoute to render a full-screen skeleton loader until _hasHydrated is true, then perform the auth check
  5. Remove the setTimeout entirely

Acceptance Criteria

  • No protected content is visible before the auth check completes on any device speed
  • A full-screen skeleton (not null) renders during hydration
  • _hasHydrated resolves correctly on cold start, page refresh, and back-navigation
  • Verified with Chrome DevTools CPU throttling set to 6x slowdown
  • No setTimeout or arbitrary delay remains in auth initialization code

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions