Skip to content

fix: Prevent Vite reload from canceling logout redirect (#23375) (CP: 24.9)#23392

Merged
caalador merged 1 commit into24.9from
cherry/cherrypick-23375-to-24.9
Feb 2, 2026
Merged

fix: Prevent Vite reload from canceling logout redirect (#23375) (CP: 24.9)#23392
caalador merged 1 commit into24.9from
cherry/cherrypick-23375-to-24.9

Conversation

@mcollovati
Copy link
Collaborator

When a user logs out and the session is invalidated, the server closes WebSocket connections with close code 1008 (VIOLATED_POLICY). Vite detects this disconnection and starts polling for reconnection, then reloads the page - canceling any server-initiated redirect.

The fix uses a Promise-based synchronization between Vite's HMR events:

  1. On vite:ws:connect, we register a close listener and store a Promise on the WebSocket that resolves with the close code when triggered.

  2. On vite:ws:disconnect, we await this Promise to get the close code. Since Vite's notifyListeners awaits our async handler, this creates a synchronization point before Vite checks its willUnload flag.

  3. When close code is 1008, we dispatch a beforeunload event to set Vite's internal willUnload flag, preventing the reload.

This approach works because Vite's close handler does not await the Promise returned by onMessage/handleMessage, so our async disconnect handler can complete (setting willUnload) before Vite's willUnload check runs.

Fixes #20819

@mcollovati mcollovati force-pushed the cherry/cherrypick-23375-to-24.9 branch from 8c2ded1 to 79f636c Compare February 2, 2026 10:17
When a user logs out and the session is invalidated, the server closes
WebSocket connections with close code 1008 (VIOLATED_POLICY). Vite
detects this disconnection and starts polling for reconnection, then
reloads the page - canceling any server-initiated redirect.

The fix uses a Promise-based synchronization between Vite's HMR events:

1. On vite:ws:connect, we register a close listener and store a Promise
   on the WebSocket that resolves with the close code when triggered.

2. On vite:ws:disconnect, we await this Promise to get the close code.
   Since Vite's notifyListeners awaits our async handler, this creates
   a synchronization point before Vite checks its willUnload flag.

3. When close code is 1008, we dispatch a beforeunload event to set
   Vite's internal willUnload flag, preventing the reload.

This approach works because Vite's close handler does not await the
Promise returned by onMessage/handleMessage, so our async disconnect
handler can complete (setting willUnload) before Vite's willUnload
check runs.

Fixes #20819
@mcollovati mcollovati force-pushed the cherry/cherrypick-23375-to-24.9 branch from 79f636c to 6ebdc0d Compare February 2, 2026 10:18
@github-actions github-actions bot added the +0.0.1 label Feb 2, 2026
@mcollovati mcollovati marked this pull request as draft February 2, 2026 10:26
@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 2, 2026

@mcollovati mcollovati marked this pull request as ready for review February 2, 2026 10:33
@github-actions
Copy link

github-actions bot commented Feb 2, 2026

Test Results

1 272 files  + 1  1 272 suites  +1   1h 13m 40s ⏱️ - 1m 8s
8 773 tests + 3  8 710 ✅ + 3  63 💤 ±0  0 ❌ ±0 
9 101 runs   - 22  9 031 ✅  - 23  70 💤 +1  0 ❌ ±0 

Results for commit 6ebdc0d. ± Comparison against base commit b725bc6.

@caalador caalador merged commit 6e83638 into 24.9 Feb 2, 2026
28 checks passed
@caalador caalador deleted the cherry/cherrypick-23375-to-24.9 branch February 2, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants