4

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?

2 Answers 2

1

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.

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

1 Comment

Thanks... however this way I would have to have a different url structure, and would not be a valid query parameter but a route itself. Ended up using the localstorage
1

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();
}

4 Comments

I think local storage would be bad if you open multiple tabs
@GlenRynaldi its a single page application, user should not be opening multi tabs.
Wait, single page app doesn't mean one tab opened
@Vega Correct, I doesn't, but to clarify, on my application user should not be using multiple tabs.

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.