Upgrading go_router 13 to 14
Breaking13.2.5 → 14.8.1Breaking1Security1Platform1New6Changed2Fixed11Other9
SecuritySecures the canPop method against missing matches in the routerDelegate configuration.Advisory ↗
BreakingUpgrade verdict
1 breaking change and a platform requirement change and a security fix.
In plain terms
- If you use GoRouteData and override onExit, you must update it to accept two arguments: the build context and the router state.
- This version requires Flutter 3.22 or newer and Dart 3.4 or newer.
- Fixes a case where checking whether the app can go back could misbehave when the router has no matching routes configured.
Must act 3 items need code or config changes
go_router publishes an official migration guide for version 14. It covers more than the release notes do.
Migrating to go_router 14 ↗Dart SDK requirement changed in 14.6.3: >=3.2.0 <4.0.0 → ^3.4.0.
Flutter requirement changed in 14.6.3: >=3.16.0 → >=3.22.0.
What you must change
Breaking1
GoRouteData's onExit now takes 2 parameters: BuildContext context and GoRouterState state.
GoRouteDataonExitBuildContextGoRouterStateSecurity1
Secures the canPop method against missing matches in the routerDelegate configuration.
canPoprouterDelegatePlatform1
Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
API changes
Generated by DepDelta from published Dart source. Not mixed with prose notes.
- removed:
field GoRoute.redirect: final GoRouterRedirect? - removed:
field StatefulNavigationShellState.Widget>: final Map<Key, Widget> - changed:
ctor GoRoute({ required this.path, this.name, this.builder, this.pageBuilder, super.parentNavigatorKey, this.redirect, this.onExit, super.routes = …, }) → ctor GoRoute({ required this.path, this.name, this.builder, this.pageBuilder, super.parentNavigatorKey, super.redirect, this.onExit, super.routes = …, }) - changed:
ctor GoRouteInformationProvider({ required String initialLocation, required Object? initialExtra, Listenable? refreshListenable, }) → ctor GoRouteInformationProvider({ required String initialLocation, required Object? initialExtra, Listenable? refreshListenable, bool routerNeglect = …, }) - changed:
ctor ShellRoute({ this.builder, this.pageBuilder, this.observers, required super.routes, super.parentNavigatorKey, GlobalKey<NavigatorState>? navigatorKey, this.restorationScopeId, }) → ctor ShellRoute({ super.redirect, this.builder, this.pageBuilder, this.observers, required super.routes, super.parentNavigatorKey, GlobalKey<NavigatorState>? navigatorKey, this.restorationScopeId, }) - changed:
ctor ShellRouteContext({ required this.route, required this.routerState, required this.navigatorKey, required this.routeMatchList, required this.navigatorBuilder, }) → ctor ShellRouteContext({ required this.route, required this.routerState, required this.navigatorKey, required this.match, required this.routeMatchList, required this.navigatorBuilder, }) - changed:
ctor StatefulShellBranch({ required this.routes, GlobalKey<NavigatorState>? navigatorKey, this.initialLocation, this.restorationScopeId, this.observers, }) → ctor StatefulShellBranch({ required this.routes, GlobalKey<NavigatorState>? navigatorKey, this.initialLocation, this.restorationScopeId, this.observers, this.preload = …, }) - changed:
ctor StatefulShellRoute({ required this.branches, this.builder, this.pageBuilder, required this.navigatorContainerBuilder, super.parentNavigatorKey, this.restorationScopeId, }) → ctor StatefulShellRoute({ required this.branches, super.redirect, this.builder, this.pageBuilder, required this.navigatorContainerBuilder, super.parentNavigatorKey, this.restorationScopeId, GlobalKey<StatefulNavigationShellState>? key, }) - changed:
ctor StatefulShellRoute.indexedStack({ required List<StatefulShellBranch> branches, StatefulShellRouteBuilder? builder, GlobalKey<NavigatorState>? parentNavigatorKey, StatefulShellRoutePageBuilder? pageBuilder, String? restorationScopeId, }) → ctor StatefulShellRoute.indexedStack({ required List<StatefulShellBranch> branches, GoRouterRedirect? redirect, StatefulShellRouteBuilder? builder, GlobalKey<NavigatorState>? parentNavigatorKey, StatefulShellRoutePageBuilder? pageBuilder, String? restorationScopeId, GlobalKey<StatefulNavigationShellState>? key, }) - changed:
method GoRouter.goNamed( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, Object? extra, }): void → method GoRouter.goNamed( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, Object? extra, String? fragment, }): void - changed:
method GoRouter.namedLocation( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, }): String → method GoRouter.namedLocation(String name, {Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, String? fragment}): String - changed:
method GoRouterHelper.goNamed( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, Object? extra, }): void → method GoRouterHelper.goNamed( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, Object? extra, String? fragment, }): void - changed:
method GoRouterHelper.namedLocation( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, }): String → method GoRouterHelper.namedLocation( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, String? fragment, }): String - changed:
method GoRouterState.namedLocation( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, String> queryParameters = …, String>{}, }): String → method GoRouterState.namedLocation( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, String> queryParameters = …, String>{}, String? fragment, }): String - changed:
method RouteConfiguration.findMatch(String location, {Object? extra}): RouteMatchList → method RouteConfiguration.findMatch(Uri uri, {Object? extra}): RouteMatchList - changed:
method RouteConfiguration.namedLocation( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, }): String → method RouteConfiguration.namedLocation( String name, { Map<String, String> pathParameters = …, String>{}, Map<String, dynamic> queryParameters = …, dynamic>{}, String? fragment, }): String - changed:
static method StatefulShellBranchData.$branch<T extends StatefulShellBranchData>({ GlobalKey<NavigatorState>? navigatorKey, List<RouteBase> routes = …, List<NavigatorObserver>? observers, String? initialLocation, String? restorationScopeId, }): StatefulShellBranch → static method StatefulShellBranchData.$branch<T extends StatefulShellBranchData>({ GlobalKey<NavigatorState>? navigatorKey, List<RouteBase> routes = …, List<NavigatorObserver>? observers, String? initialLocation, String? restorationScopeId, bool preload = …, }): StatefulShellBranch - changed:
typedef ExitCallback = FutureOr<bool> Function(BuildContext context) → typedef ExitCallback = FutureOr<bool> Function( BuildContext context, GoRouterState state) - changed:
typedef NavigatorBuilder = Widget Function( List<NavigatorObserver>? observers, String? restorationScopeId) → typedef NavigatorBuilder = Widget Function( GlobalKey<NavigatorState> navigatorKey, ShellRouteMatch match, RouteMatchList matchList, List<NavigatorObserver>? observers, String? restorationScopeId) - added:
field RouteBase.redirect: final GoRouterRedirect? - added:
field ShellRouteContext.match: final ShellRouteMatch - added:
field StatefulShellBranch.preload: final bool - added:
get GoRouter.state: GoRouterState - added:
get GoRouterDelegate.state: GoRouterState - added:
get StatefulNavigationShell.debugLoadedBranches: List<StatefulShellBranch> - added:
method GoRouteData.onExit(BuildContext context, GoRouterState state): FutureOr<bool> - added:
method ShellRouteData.redirect(BuildContext context, GoRouterState state): FutureOr<String?> - added:
method StatefulShellRouteData.redirect(BuildContext context, GoRouterState state): FutureOr<String?>