Skip to content

[go_router] Fix pages dropped when switching to an unloaded branch - #12422

Open
Yusufihsangorgel wants to merge 5 commits into
flutter:mainfrom
Yusufihsangorgel:issue-188295-preserve-parent-pages
Open

[go_router] Fix pages dropped when switching to an unloaded branch#12422
Yusufihsangorgel wants to merge 5 commits into
flutter:mainfrom
Yusufihsangorgel:issue-188295-preserve-parent-pages

Conversation

@Yusufihsangorgel

@Yusufihsangorgel Yusufihsangorgel commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Switching a StatefulShellRoute to a branch that has not been loaded yet drops the pages a parent Navigator holds below the shell, which is why the back button disappears in the issue's repro. goBranch with initialLocation: true takes the same path. Both call _router.go with the branch's initial location. go rebuilds the match list from that location alone.

This grafts the shell match for the initial location into the current match list so the parent's matches survive, and takes extra from that location's match list so the outer extra does not leak in. A location with no shell match still goes through go.

A branch initial location that redirects still loses the graft, since restore keeps the supplied list only when the URI is unchanged. The shell lookup also repeats the one in _preloadBranches. I raised both on the issue on 07-31 and took the smaller change here.

Fixes flutter/flutter#188295

Pre-Review Checklist

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2

Grafting the shell match for a branch's initial location kept the current
match list's extra, so an object passed to the outer location reached a
branch that never asked for it. Take the extra from the match list built
for the initial location instead, which is what GoRouter.go would produce.
findMatch returns an error only when it matched nothing, and an empty
match list already leaves newShellMatch null, so the second disjunct
never decides the outcome.
@github-actions github-actions Bot added p: go_router triage-framework Should be looked at in framework triage labels Aug 10, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request modifies StatefulNavigationShellState in go_router to preserve parent navigator pages when switching to an unloaded branch of a StatefulShellRoute by grafting the branch's initial match list into the current match list. It also adds tests to verify this behavior and ensure that extra parameters do not leak. The review feedback suggests simplifying the loop logic in _initialMatchListForBranch for finding newShellMatch to improve readability.

Comment on lines +1501 to +1505
ShellRouteMatch? newShellMatch;
initialMatchList.visitRouteMatches((RouteMatchBase match) {
newShellMatch = match is ShellRouteMatch && match.route == route ? match : newShellMatch;
return newShellMatch == null;
});

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.

medium

The current logic for finding newShellMatch and returning the loop control boolean can be simplified to improve readability and reduce cognitive load. Using an explicit if statement with an early return of false is more idiomatic and easier to understand at a glance.

Suggested change
ShellRouteMatch? newShellMatch;
initialMatchList.visitRouteMatches((RouteMatchBase match) {
newShellMatch = match is ShellRouteMatch && match.route == route ? match : newShellMatch;
return newShellMatch == null;
});
ShellRouteMatch? newShellMatch;
initialMatchList.visitRouteMatches((RouteMatchBase match) {
if (match is ShellRouteMatch && match.route == route) {
newShellMatch = match;
return false;
}
return true;
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. The old return inferred the stop from newShellMatch instead of saying it at the match.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

p: go_router triage-framework Should be looked at in framework triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[go_router]when navigator have routes pushed before statefullshellroute, switch to diffrent branch of statefullshellroute, the behavior is very strange

1 participant