caiovisk
caiovisk

Reputation: 3809

Flutter web to persist the URL Query String parameter on route change. Flutter white labelling

The Flutter web app I am building have a white label feature that is based on the URL query string /#?brd=BrandName... by the requirements, the white label must work based on the url parameter brd as domain will be the same for all brands.

Currently it works fine and loads the correct info, however if user navigates once and refreshes the page it falls back to main brand as the query parameter brd is not present.

Is there a way in flutter to persist the query parameters on every route change?

Upvotes: 3

Views: 1352

Answers (2)

caiovisk
caiovisk

Reputation: 3809

Ended up using localstorage package. In this way I don't need to change or mess up with the routes.

Basically on the initialisation I check if the brand is there or not, and set it into the browser local storage.

void brandChecker() async {
  //get brd queryParameter e.g: ?brd=BrandName
  String? urlBrd = Uri.base.queryParameters["brd"];
  final LocalStorage storage = LocalStorage('setBrd');
  await storage.ready;
  //get any stored brand from localStorage, null if none
  String? selectedBrd = storage.getItem('brd');

  if (urlBrd != null && selectedBrd != null && urlBrd != selectedBrd) {
    brand = getBrand(urlBrd.toString());
  } else {
    //If brand is not provided check the local storage otherwise fallback getBrand
    brand = (selectedBrd != null) ? selectedBrd.toString() : getBrand(urlBrd.toString());
  }

  storage.setItem('brd', brand);
  brandSetup();
}

Upvotes: 1

igdmitrov
igdmitrov

Reputation: 546

Try this:

  1. Remove your initialRoute and routes from MaterialApp (if you use Material).

  2. Use only onGenerateRoute e.g.:

onGenerateRoute: (settings) {
        print(settings);

        if (settings.name!.contains('?brd=BrandName') == false) {
          return MaterialPageRoute(
            builder: (context) {
              return const HomePage();
            },
            settings: RouteSettings(
                name: '?brd=BrandName', arguments: settings.arguments),
          );
        }

        if (settings.name!.contains(DetailsPage.routeName)) {
          final List<String> uri = settings.name!.split('/');

          if (uri.length == 3) {
            return MaterialPageRoute(
              builder: (context) {
                return DetailsPage(pageId: uri[2]);
              },
              settings: settings,
            );
          }
        }

        return MaterialPageRoute(
          builder: (context) {
            return const HomePage();
          },
          settings: settings,
        );
      },

In my example I have two pages:

Home - /#?brd=BrandName

Details - /#?brd=BrandName/details/2

Example with button:

ElevatedButton(
              onPressed: () {
                navigatorKey.currentState!
                    .pushNamed("?brd=BrandName/details/2");
              },
              child: const Text('Go to Page 1'),
            )

P.S. When you change something in routers it is much better to reboot your application completely.

Upvotes: 1

Related Questions