[Intercepted parallel routes] Fix an issue when calling redirect in a server action from within an intercepted route
#86961
+293
−1
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.
What?
When calling the
redirectfunction in a server action from within a intercepted parallel route, the intercepted route's content would remain visible on screen, and the redirect would never happenWhy?
The bug stems from intentional behavior in the
applyPatchfunction (inapply-router-state-patch-to-tree.ts) that preserves parallel route state during navigation:This logic exists for a good reason: parallel routes should persist across navigations. For example, if you have a sidebar (
@sidebar) and navigate between pages, the sidebar content should remain visible rather than being replaced with__DEFAULT__(which would renderdefault.tsx/null).The Problem with Server Action Redirects
When a server action calls
redirect('/'):Current tree has the intercepted modal:
Server response contains
__DEFAULT__for the modal slot:applyPatchsees:patchSegment === "__DEFAULT__"andinitialSegment === "(slot)"(not__DEFAULT__)Result: The function returns
initialTree, preserving the intercepted modal content instead of replacing it with__DEFAULT__Why This Is Wrong for Redirects
The parallel route preservation logic makes sense for soft navigations (clicking links, using
router.push), where users expect UI state to persist. But for server action redirects, the expectation is different:The Fix
The fix cleans intercepted routes from the current tree when a redirect is detected before applying the patch during redirects. This allows the server's
__DEFAULT__segment to be properly applied, effectively closing the modal: