This same question I faced while I tried Flutter Web, I tried angular type routing for the path and queries param. It is working perfectly but there is not provided child routing. For the path parsing use path_to_regexp and use URI for the queryParams.
pubspec.yaml
path_to_regexp: ^0.4.0
activated_routes.dart
import 'package:flutter/material.dart';
import 'package:path_to_regexp/path_to_regexp.dart';
typedef RoutingParameters = Route Function(
RouteSettings settings,
Map<String, dynamic> param,
);
class _RoutingParametersHandler {
final String path;
final RoutingParameters routingParameters;
_RoutingParametersHandler(this.path, this.routingParameters);
}
class ActivatedRoutes {
static final ActivatedRoutes _instance = ActivatedRoutes._();
ActivatedRoutes._();
static ActivatedRoutes get instance => _instance;
final List<_RoutingParametersHandler> _routingList = [];
void addRoute(String path, RoutingParameters routingParameters) {
_routingList.add(_RoutingParametersHandler(path, routingParameters));
}
Route? onGeneratedRoute(RouteSettings settings) {
Uri uri = Uri.parse(settings.name ?? '');
_RoutingParametersHandler? routingHandler;
Map<String, dynamic> param = {};
for (var element in _routingList) {
final parameters = <String>[];
final tokens = parse(element.path, parameters: parameters);
final regExp = tokensToRegExp(tokens);
if (regExp.hasMatch(uri.path)) {
routingHandler = element;
final match = regExp.matchAsPrefix(uri.path);
Map<String, String> pathParamMap = extract(parameters, match!);
pathParamMap.forEach((key, value) {
param[key] = value;
});
}
}
if (uri.queryParameters.isNotEmpty) {
uri.queryParameters.forEach((key, value) {
param[key] = value;
});
}
if (routingHandler != null) {
return routingHandler.routingParameters(settings, param);
}
return null;
}
}
routes.dart
import 'package:flutter/material.dart';
class Routes {
static setUpRoute() {
ActivatedRoutes.instance.addRoute('/', (settings, params) {
return MaterialPageRoute(
settings: settings,
builder: (context) => const LoginPage(),
);
});
ActivatedRoutes.instance.addRoute('/dashboard/:id', (settings, params) {
print(params)
return MaterialPageRoute(
settings: settings,
builder: (context) => const DashboardPage(),
);
});
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
useWebConfig();
Routes.setUpRoute();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
onGenerateRoute: (settings) =>
ActivatedRoutes.instance.onGeneratedRoute(settings),
);
}
}
routing_ext.dart
import 'package:flutter/material.dart';
extension ContextNavigatorExtension on BuildContext {
pushNamed(
String path, {
Map<String, dynamic>? queryParameters,
Object? arguments,
}) {
Navigator.pushNamed(
this,
Uri(
path: path,
queryParameters: queryParameters,
).toString(),
arguments: arguments,
);
}
}
for the navigation use below code:
context.pushNamed(
'/dashboard/59',
queryParameters: {
'data': 'Hello!',
},
);
Output:
http://localhost:60031/dashboard/59?data=Hello!
{id: 59, data: Hello!}