Skip to content

fix(react): Fix stale SSR state during cross-tab sign-out#7865

Merged
bratsos merged 2 commits into
mainfrom
alexbratsos/user-4721-navigations-can-hang-in-dev-build
Feb 19, 2026
Merged

fix(react): Fix stale SSR state during cross-tab sign-out#7865
bratsos merged 2 commits into
mainfrom
alexbratsos/user-4721-navigations-can-hang-in-dev-build

Conversation

@bratsos

@bratsos bratsos commented Feb 17, 2026

Copy link
Copy Markdown
Member

Description

When a user signs out in one browser tab, other tabs viewing protected pages hang instead of redirecting to the sign-in page. The page remains stuck showing stale authentication data even though the session has been terminated.

Reproduction:

  • Open two tabs, both authenticated and viewing a protected page
  • Sign out in Tab 2 using UserButton
  • Tab 1 should detect the sign-out and redirect to sign-in
  • Bug: Tab 1 hangs showing stale session data instead of redirecting

Root Cause

The issue was in @clerk/nextjs App Router awaitable navigation:

  • RedirectToSignIn can trigger duplicate router.push calls to the same destination while the first transition is still in flight (commonly observed in dev/StrictMode-like remount/effect replay behavior).
  • The awaitable nav buffer accepted both calls and started another transition for the same URL.
  • In this duplicate in-flight scenario, Next.js may dedupe/cancel the redundant action, leaving isPending stuck and preventing promise buffer flush.

Result: redirect flow appears hung even though auth state is already signed out.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • Bug Fixes

    • Resolved an App Router navigation edge case: coalesces duplicate in-flight redirects to the same destination and resets pending navigation state after flush to prevent hangs.
  • Tests

    • Added unit tests for in-flight navigation deduplication, differing destinations, and re-navigation after flush.
  • Chores

    • Added a changeset with a patch version bump for the Next.js package.

@vercel

vercel Bot commented Feb 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Feb 19, 2026 7:24pm

Request Review

@changeset-bot

changeset-bot Bot commented Feb 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a850c4c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clerk/nextjs Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Feb 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7865

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7865

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7865

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7865

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7865

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7865

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7865

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7865

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7865

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7865

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7865

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7865

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7865

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7865

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7865

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7865

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7865

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7865

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7865

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7865

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7865

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7865

commit: a850c4c

@coderabbitai

coderabbitai Bot commented Feb 17, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds a changeset for a patch bump to @clerk/nextjs. Updates useInternalNavFun to track a shared pendingDestination and a shared promisesBuffer so duplicate in-flight navigations to the same destination are coalesced and resolved together; the implementation sets pendingDestination before starting a navigation and clears it on flush. Adds pendingDestination?: string to Window.__clerk_internal_navigations in global.d.ts. Includes new tests exercising deduplication, non-deduplication for different targets, and allowing a new same-destination push after a flush.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'fix(react): Fix stale SSR state during cross-tab sign-out' is misleading; the actual changes are in the Next.js App Router awaitable navigation deduplication logic, not SSR state or React core. Revise the title to accurately reflect the main change, such as 'fix(nextjs): Deduplicate in-flight App Router navigations to prevent hanging redirects' or similar.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR successfully addresses USER-4721 by implementing deduplication for in-flight transitions in useInternalNavFun, preventing duplicate router.push calls to the same destination from leaving navigation pending indefinitely.
Out of Scope Changes check ✅ Passed All changes are in-scope: changeset entry documents the patch, global.d.ts augments navigation state tracking, useInternalNavFun implements deduplication logic, and the test file validates the new behavior comprehensively.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.changeset/dry-mangos-fail.md (1)

5-5: Consider adding cross-tab scenario context.

The description is clear and technically accurate. For enhanced user understanding, you could optionally mention the specific cross-tab scenario (e.g., "when signing out in one browser tab while other tabs remain open").

📝 Optional enhancement for user clarity
-Fix navigation hang on cross-tab sign-out by preventing stale SSR state from being used after sign-out detection.
+Fix navigation hang when signing out in one browser tab while other authenticated tabs remain open, by preventing stale SSR state from being used after sign-out detection.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.changeset/dry-mangos-fail.md at line 5, Update the changeset description
"Fix navigation hang on cross-tab sign-out by preventing stale SSR state from
being used after sign-out detection." to explicitly mention the cross-tab
scenario (for example: "when signing out in one browser tab while other tabs
remain open") so users immediately understand the context; keep the technical
explanation about preventing stale SSR state after sign-out detection (the
existing phrase) and append a short example clause referencing the cross-tab
sign-out behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.changeset/dry-mangos-fail.md:
- Line 5: Update the changeset description "Fix navigation hang on cross-tab
sign-out by preventing stale SSR state from being used after sign-out
detection." to explicitly mention the cross-tab scenario (for example: "when
signing out in one browser tab while other tabs remain open") so users
immediately understand the context; keep the technical explanation about
preventing stale SSR state after sign-out detection (the existing phrase) and
append a short example clause referencing the cross-tab sign-out behavior.

@jacekradko jacekradko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bratsos I am wondering if other hooks like useUserBase for example have the same issue of returning stale initialState ?

Comment thread packages/react/src/hooks/useAuthBase.tsx Outdated
@bratsos bratsos force-pushed the alexbratsos/user-4721-navigations-can-hang-in-dev-build branch from f861ecc to d81e40f Compare February 18, 2026 19:34
@bratsos

bratsos commented Feb 18, 2026

Copy link
Copy Markdown
Member Author

@bratsos I am wondering if other hooks like useUserBase for example have the same issue of returning stale initialState ?

I completely changed the directory, this was indeed not the issue. Please check again! 🙏

@bratsos bratsos requested a review from Ephem February 18, 2026 19:38
Comment thread .changeset/cozy-lemons-crash.md Outdated

@Ephem Ephem left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a pragmatic fix, nice find! 🙏

Comment thread .changeset/cozy-lemons-crash.md Outdated
@bratsos bratsos force-pushed the alexbratsos/user-4721-navigations-can-hang-in-dev-build branch from c683ba9 to fc44a98 Compare February 19, 2026 13:19
@bratsos bratsos merged commit 37a4cbb into main Feb 19, 2026
67 of 68 checks passed
@bratsos bratsos deleted the alexbratsos/user-4721-navigations-can-hang-in-dev-build branch February 19, 2026 19:46
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.

4 participants