diff --git a/.changeset/full-showers-serve.md b/.changeset/full-showers-serve.md new file mode 100644 index 00000000000..242b674902f --- /dev/null +++ b/.changeset/full-showers-serve.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-react': patch +--- + +Ensure that useAuth() hook returns isLoaded=false when isomorphicClerk is loaded but we are in transitive state diff --git a/packages/react/src/hooks/__tests__/useAuth.test.tsx b/packages/react/src/hooks/__tests__/useAuth.test.tsx index fcffe1bdc17..a352e6c73b3 100644 --- a/packages/react/src/hooks/__tests__/useAuth.test.tsx +++ b/packages/react/src/hooks/__tests__/useAuth.test.tsx @@ -77,6 +77,39 @@ describe('useAuth', () => { ); }).not.toThrow(); }); + + test('returns isLoaded false when isomorphicClerk is loaded but in transitive state', () => { + const mockIsomorphicClerk = { + loaded: true, + telemetry: { record: vi.fn() }, + }; + + const mockAuthContext = { + actor: undefined, + factorVerificationAge: null, + orgId: undefined, + orgPermissions: undefined, + orgRole: undefined, + orgSlug: undefined, + sessionClaims: null, + sessionId: undefined, + sessionStatus: undefined, + userId: undefined, + }; + + const { result } = renderHook(() => useAuth(), { + wrapper: ({ children }) => ( + + {children} + + ), + }); + + expect(result.current.isLoaded).toBe(false); + expect(result.current.isSignedIn).toBeUndefined(); + expect(result.current.sessionId).toBeUndefined(); + expect(result.current.userId).toBeUndefined(); + }); }); describe('useDerivedAuth', () => { diff --git a/packages/react/src/hooks/useAuth.ts b/packages/react/src/hooks/useAuth.ts index ba0da72f9cf..3a92f56aa6c 100644 --- a/packages/react/src/hooks/useAuth.ts +++ b/packages/react/src/hooks/useAuth.ts @@ -99,13 +99,9 @@ export const useAuth = (initialAuthStateOrOptions: UseAuthOptions = {}): UseAuth const initialAuthState = rest as any; const authContextFromHook = useAuthContext(); - let authContext = authContextFromHook; - - if (authContext.sessionId === undefined && authContext.userId === undefined) { - authContext = initialAuthState != null ? initialAuthState : {}; - } - const isomorphicClerk = useIsomorphicClerkContext(); + const authContext = !isomorphicClerk.loaded && initialAuthState ? initialAuthState : authContextFromHook; + const getToken: GetToken = useCallback(createGetToken(isomorphicClerk), [isomorphicClerk]); const signOut: SignOut = useCallback(createSignOut(isomorphicClerk), [isomorphicClerk]);