spa: populate user state when not already hydrated#619
Merged
larbish merged 2 commits intoMay 21, 2026
Conversation
|
@XStarlink is attempting to deploy a commit to the NuxtLabs Team on Vercel. A member of the Team first needs to authorize it. |
commit: |
The previous guard `if (!useSsrCookies)` skipped the pre-population of `currentSession` and `currentUser` whenever SSR cookies were enabled, assuming the server plugin had already populated the state during SSR. This assumption breaks when `ssr: false` is set globally: the server plugin never runs, so the state remains null when route middlewares execute, causing users to be redirected to `/login` on refresh even when authenticated (race resolves later via the `INITIAL_SESSION` event). Switching the guard to check the state itself (`!currentSession.value`) covers both code paths: it stays a no-op in SSR mode where the state is already hydrated, while correctly populating it in SPA mode regardless of the `useSsrCookies` option. Closes nuxt-modules#565 Co-authored-by: Cursor <cursoragent@cursor.com>
10eba91 to
f1056da
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #565
Types of changes
Description
PR #594 (v2.0.7) fixed
useSupabaseUser()returningnullin middlewares on refresh, but only whenuseSsrCookies: false. The race condition persists whenssr: falseis set globally anduseSsrCookies: trueis kept (the default).This is a very common combo: a SPA frontend that calls a Nitro/server backend relying on
serverSupabaseUser()for auth — users can't disableuseSsrCookiesbecause the server needs the session cookie to identify users in API routes.Problem
The previous guard
if (!useSsrCookies)skipped the pre-population ofcurrentSessionandcurrentUserwhenever SSR cookies were enabled, assuming the server plugin had already populated the state during SSR.When
ssr: falseis set globally, that assumption breaks:supabase.server.tsnever runs (no server render).supabase.client.tsreturns fromsetup()without touchingcurrentSession/currentUser.createBrowserClientreads the session asynchronously via theINITIAL_SESSIONevent, which fires after route middlewares.Resulting timeline:
Fix
Switch the guard to check the state itself (
!currentSession.value) instead of the config:Behaviour matrix:
currentSession.valueon client setupuseSsrCookies: trueuseSsrCookies: truenull(server plugin didn't run)useSsrCookies: false(any mode)nullIt's a no-op in SSR mode and correctly populates the state in SPA mode regardless of the
useSsrCookiesoption.Test plan
Verified locally on a project with
ssr: false+useSsrCookies: true+ custom middlewares usinguseSupabaseUser(). Before the patch: intermittent redirect to/loginon refresh. After the patch: no redirect on 15+ consecutive refreshes, including incognito mode and after manual cookie deletion.Checklist:
No tests added: the bug is a race condition tied to Nuxt's plugin/middleware/
page:startordering in SPA mode, which is non-trivial to assert in the existing unit-test setup. Happy to add a fixture-based integration test if a maintainer can point me to the right pattern.