@@ -356,6 +356,18 @@ export const loginAtom = atom(
356356 // with other components that might react to the auth state change.
357357 set ( loginActionInProgressAtom , true ) ;
358358
359+ // Set pendingRedirectAtom to trigger navigation BEFORE stabilization.
360+ // This ensures that RedirectHandler sees both loginActionInProgress and
361+ // the pendingRedirect at the same time, avoiding race conditions.
362+ let redirectTarget = nextPath && nextPath . startsWith ( '/' ) ? nextPath : '/' ;
363+ // Ensure we don't redirect back to the login page after a successful login.
364+ // Check just the pathname part of the target, ignoring query params.
365+ const redirectPathname = redirectTarget . split ( '?' ) [ 0 ] ;
366+ if ( redirectPathname === '/login' ) {
367+ redirectTarget = '/' ;
368+ }
369+ set ( pendingRedirectAtom , redirectTarget ) ;
370+
359371 // Update auth status directly from login response to avoid a re-fetch race condition.
360372 const newAuthStatus = _parseAuthStatusRpcResponseToAuthStatus ( responseData ) ;
361373 set ( authStatusCoreAtom , Promise . resolve ( newAuthStatus ) ) ;
@@ -366,17 +378,6 @@ export const loginAtom = atom(
366378 set ( updateSyncTimestampAtom , Date . now ( ) ) ;
367379 }
368380
369- // Set pendingRedirectAtom to trigger navigation.
370- // Prioritize nextPath if available and valid, otherwise default to '/'.
371- let redirectTarget = nextPath && nextPath . startsWith ( '/' ) ? nextPath : '/' ;
372- // Ensure we don't redirect back to the login page after a successful login.
373- // Check just the pathname part of the target, ignoring query params.
374- const redirectPathname = redirectTarget . split ( '?' ) [ 0 ] ;
375- if ( redirectPathname === '/login' ) {
376- redirectTarget = '/' ;
377- }
378- set ( pendingRedirectAtom , redirectTarget ) ;
379-
380381 } catch ( error ) {
381382 console . error ( '[loginAtom] Login attempt failed.' ) ; // Less verbose for production
382383 // Refresh to ensure we have the latest (likely unauthenticated) status.
0 commit comments