3

I'm facing an issue with Go Router in Flutter where the current page gets reloaded when pushing to a new page. Specifically, when I'm on the "/home" page (which is a part of a shell route) and push to the "/staff_profile" page using context.push, the "/home" page gets reloaded in the background.

Here's the relevant code snippet from my Go Router configuration:

Home

static final router = GoRouter(
    navigatorKey: _mainNavigatorKey,
    observers: [
      GoRouterObserver(
        analytics: FirebaseAnalytics.instance,
      )
    ],
    routes: [
      ShellRoute(
        observers: [
          GoRouterObserver(
            analytics: FirebaseAnalytics.instance,
          )
        ],
        builder: (context, state, child) {
          ... // code
        },
        routes: <RouteBase>[
          GoRoute(
            path: '/home',
            builder: (context, state) => HomeFragemnt(
              onNotificationIconTab: (){

              }, userRepository: RepositoryProvider.of<UserRepository>(context),
              coSoRepository: RepositoryProvider.of<CoSoRepository>(context),
              reportRepository: RepositoryProvider.of<ReportRepository>(context),
              onTabDetailTipSummary: (branchGuid , timeReport , time ) {
                context.push('/technician_tip_league?branchGuid=$branchGuid&timeReport=$timeReport&time=$time');
              },
              onTabStaff: (staffGuid){
                context.push('/staff_profile?nhanVienGuid=$staffGuid');
              }, onRevenueTimeChartTab: (branchGuid , timeReport ) {
              context.push('/revenue_by_parent_time?branchGuid=$branchGuid&timeReport=$timeReport');
            },
            ),
          ),

staff_profile

 GoRoute(
        path: '/resource_staff',
        builder: (context, state){
          var branchGuid = state.uri.queryParameters['branchGuid'].toString();
          return StaffSummaryDetail(
            reportRepository: RepositoryProvider.of<ReportRepository>(context),
            branchGuid: branchGuid,
            onTabStaffInfo: (postion , ageMin , ageMax , coSoGuid ) {
              context.push('/staff_list?position=$postion&ageMin=$ageMin&ageMax=$ageMax&coSoGuid=$coSoGuid');
            },
          );
        },
      ),

The expected behavior is that the "/home" page should not reload when pushing the "/staff_profile" page onto the navigation stack. However, if I use Navigator.push instead of context.push, the current page does not reload in the background.

Can anyone help me understand why the current page is reloading when using context.push with Go Router, and suggest a solution to prevent this behavior, especially when the current page is a part of a shell route? I've tried both pageBuilder and builder for the home route, but the issue persists.

Please let me know if you need any additional information or clarification.

1 Answer 1

0

This is usually a rebuild, not a true reload.

When you call context.push(...), go_router recalculates the matched route tree.
If /home is inside a ShellRoute, that page can rebuild in the background when you push /staff_profile.

So the main problem is often not navigation itself, but that the /home page is doing work during rebuild.

What to do

1. Move side effects out of build()

Do not start API calls, create blocs/controllers, or run expensive setup inside:

  • route builder

  • page build()

Put that logic in:

  • initState()

  • a provider/bloc above the router

  • cached state

Otherwise every rebuild will feel like a full reload.

2. Use navigator keys clearly

If staff_profile should open above the shell, push it on the root navigator:

final _rootNavigatorKey = GlobalKey<NavigatorState>();
final _shellNavigatorKey = GlobalKey<NavigatorState>();

final router = GoRouter(
  navigatorKey: _rootNavigatorKey,
  routes: [
    ShellRoute(
      navigatorKey: _shellNavigatorKey,
      builder: (context, state, child) => AppShell(child: child),
      routes: [
        GoRoute(
          path: '/home',
          parentNavigatorKey: _shellNavigatorKey,
          builder: (context, state) => const HomePage(),
        ),
      ],
    ),
    GoRoute(
      path: '/staff_profile',
      parentNavigatorKey: _rootNavigatorKey,
      builder: (context, state) {
        final staffGuid = state.uri.queryParameters['nhanVienGuid']!;
        return StaffProfilePage(staffGuid: staffGuid);
      },
    ),
  ],
);

This is the usual pattern: shell pages stay on the shell navigator, and full-screen detail pages go on the root navigator.

3. If you need branch state preserved, use StatefulShellRoute

If this is a tab/shell app and you want each branch to keep its state, StatefulShellRoute.indexedStack is usually the better choice.

In your case

Most likely /home is rebuilding because it sits inside the shell, and context.push('/staff_profile...') causes go_router to rematch the stack.

So the fix is usually:

  • keep side effects out of build

  • use parentNavigatorKey for detail pages

  • use StatefulShellRoute if you need stronger state preservation

If HomeFragment is fetching data or creating dependencies inside build, that is probably why it feels like a reload.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.