flutterflutter-navigationflutter-go-router

How to stop flutter web redirect to home screen on screen size change or interection


whenever i change screen size of my flutter web app, the screen automatically navigates to home screen Here is my main.dart codes and I am using go_router for navigation

import 'package:door_rush_web/controller/provider/categoryNSubCategoryCRUDProvider.dart';
import 'package:door_rush_web/controller/provider/locationProvider/locationProvider.dart';
import 'package:door_rush_web/controller/provider/productDataProvider/productDataProvider.dart';
import 'package:door_rush_web/firebase_options.dart';
import 'package:door_rush_web/model/subCategoryModel/subCategoryModel.dart';
import 'package:door_rush_web/view/InfoScreen/InfoScreenBuilder.dart';
import 'package:door_rush_web/view/PrivacyPolicy/privacyPolicyDesktop.dart';
import 'package:door_rush_web/view/PrivacyPolicy/privacyPolicyScreenBuilder.dart';
import 'package:door_rush_web/view/addProductScreen/addProductScreen.dart';
import 'package:door_rush_web/view/categoryNSubCategoryCRUD/categoryNSubCategoryCRUDScreen.dart';
import 'package:door_rush_web/view/homeScreen/homeScreen.dart';
import 'package:door_rush_web/view/subCategoryScreen/subCategoryScreen.dart';
import 'package:door_rush_web/widgets/scrollBehaviour.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:responsive_sizer/responsive_sizer.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const DoorRushWeb());
}

class DoorRushWeb extends StatelessWidget {
  const DoorRushWeb({super.key});

  @override
  Widget build(BuildContext context) {
    return ResponsiveSizer(builder: (context, _, __) {
      return MultiProvider(
        providers: [
          ChangeNotifierProvider<ProductDataProvider>(
            create: (_) => ProductDataProvider(),
          ),
          ChangeNotifierProvider<CategoryNSubCategoryCRUDProvider>(
            create: (_) => CategoryNSubCategoryCRUDProvider(),
          ),
          ChangeNotifierProvider<LocationProvider>(
            create: (_) => LocationProvider(),
          ),
        ],
        child: MaterialApp.router(
          scrollBehavior: MyCustomScrollBehavior(),
          debugShowCheckedModeBanner: false,
          title: 'Quickzy',
          builder: FlutterSmartDialog.init(),
          routerConfig: GoRouter(
            routes: [
              GoRoute(
                path: '/infoScreen',
                builder: (context, state) => const InfoScreenBuilder(),
              ),
              GoRoute(
                path: '/Privacy',
                builder: (context, state) => const PrivacyPolicyScreenBuilder(),
              ),
              GoRoute(
                path: '/',
                builder: (context, state) => const HomeScreen(),
              ),
              GoRoute(
                path: '/addProductScreen',
                builder: (context, state) => const AddProductScreen(),
              ),
              GoRoute(
                path: '/addProducts',
                builder: (context, state) => const AddProductScreen(),
              ),
              GoRoute(
                path: '/categories/:category',
                builder: (context, state) => SubCategoryScreen(
                  category: state.pathParameters['category']!,
                ),
              ),
              GoRoute(
                path: '/addProducts',
                builder: (context, state) =>
                    const CategoryNSubCategoryCRUDScreen(),
              ),
            ],
          ),
        ),
      );
    });
  }
}

In my Flutter web application, when the screen size changes (e.g., resizing the browser window) or when certain interactions occur, the app unintentionally navigates back to the home screen. This behavior suggests a disruption in the app's navigation flow or state preservation, leading to the loss of the current route or page context. As a result, users are redirected to the default home route instead of staying on their current page, negatively impacting the user experience and functionality.


Solution

  • This happens because ResponsiveSizer re-runs its builder method whenever the app's window is resized. Because you instantiate your GoRouter inside of the builder method, it gets reset back to its initial state whenever the window is resized. In general, it's a bad idea to define a router inside of a build method since this will cause your navigation to be reset whenever that widget is rebuilt (even with hot reload).

    Instead, define your GoRouter outside of the build method, such as in a top-level final variable:

    final _router = GoRouter(
      routes: [
        // Your routes here
      ],
    );
    
    class DoorRushWeb extends StatelessWidget {
      const DoorRushWeb({super.key});
    
      @override
      Widget build(BuildContext context) {
        return ResponsiveSizer(
          builder: (context, _, __) {
            return MultiProvider(
              providers: [
                ChangeNotifierProvider<ProductDataProvider>(
                  create: (_) => ProductDataProvider(),
                ),
                ChangeNotifierProvider<CategoryNSubCategoryCRUDProvider>(
                  create: (_) => CategoryNSubCategoryCRUDProvider(),
                ),
                ChangeNotifierProvider<LocationProvider>(
                  create: (_) => LocationProvider(),
                ),
              ],
              child: MaterialApp.router(
                scrollBehavior: MyCustomScrollBehavior(),
                debugShowCheckedModeBanner: false,
                title: 'Quickzy',
                builder: FlutterSmartDialog.init(),
                routerConfig: _router,
              ),
            );
          },
        );
      }
    }