[go_router] Applies flutter package lints (#1017)

diff --git a/.cirrus.yml b/.cirrus.yml
index fd58d13..ce62ba0 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -48,8 +48,7 @@
       always:
         format_script: ./script/tool_runner.sh format --fail-on-change
         license_script: dart pub global run flutter_plugin_tools license-check
-        # TODO(chunhtai): Remove go_router custom-analysis https://github.com/flutter/flutter/issues/98711
-        analyze_script: ./script/tool_runner.sh analyze --custom-analysis=go_router,web_benchmarks/testing/test_app,flutter_lints/example,rfw/example
+        analyze_script: ./script/tool_runner.sh analyze --custom-analysis=web_benchmarks/testing/test_app,flutter_lints/example,rfw/example
         pubspec_script: ./script/tool_runner.sh pubspec-check
     - name: publishable
       env:
diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md
index e08a182..bae35ca 100644
--- a/packages/go_router/CHANGELOG.md
+++ b/packages/go_router/CHANGELOG.md
@@ -1,6 +1,10 @@
+## 3.0.4
+
+- Updates code for stricter analysis options.
+
 ## 3.0.3
 
-- Fixed a bug where params disappear when pushing a nested route.
+- Fixes a bug where params disappear when pushing a nested route.
 
 ## 3.0.2
 
diff --git a/packages/go_router/README.md b/packages/go_router/README.md
index 4c66a6e..85f0712 100644
--- a/packages/go_router/README.md
+++ b/packages/go_router/README.md
@@ -20,15 +20,15 @@
         title: 'GoRouter Example',
       );
 
-  final _router = GoRouter(
-    routes: [
+  final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) => const Page1Screen(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) => const Page2Screen(),
       ),
     ],
   );
diff --git a/packages/go_router/analysis_options.yaml b/packages/go_router/analysis_options.yaml
deleted file mode 100644
index 53897be..0000000
--- a/packages/go_router/analysis_options.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-# This file is temporary and should be removed as a part of
-# https://github.com/flutter/flutter/issues/98711.
-analyzer:
-  exclude:
-    - "**/*.g.dart"
-    - "**/*.freezed.dart"
-    - "test/.test_coverage.dart"
-    - "bin/cache/**"
-    - "lib/generated_plugin_registrant.dart"
-  strong-mode:
-    implicit-casts: false
-    implicit-dynamic: false
-  errors:
-    included_file_warning: ignore
-    missing_required_param: error
-    missing_return: error
-    parameter_assignments: error
-
-linter:
-  rules:
-    prefer_double_quotes: false
-    unnecessary_final: false
-    always_specify_types: false
-    prefer_final_parameters: false
-    prefer_asserts_with_message: false
-    require_trailing_commas: false
-    avoid_classes_with_only_static_members: false
-    always_put_control_body_on_new_line: false
-    always_use_package_imports: false
-    avoid_annotating_with_dynamic: false
-    avoid_redundant_argument_values: false
-    one_member_abstracts: false
-    flutter_style_todos: false
diff --git a/packages/go_router/example/analysis_options.yaml b/packages/go_router/example/analysis_options.yaml
deleted file mode 100644
index 6cb1fba..0000000
--- a/packages/go_router/example/analysis_options.yaml
+++ /dev/null
@@ -1,39 +0,0 @@
-# This file is temporary and should be removed as a part of
-# https://github.com/flutter/flutter/issues/98711.
-
-include: package:all_lint_rules_community/all.yaml
-
-analyzer:
-  exclude:
-    - "**/*.g.dart"
-    - "**/*.freezed.dart"
-    - "test/.test_coverage.dart"
-    - "bin/cache/**"
-    - "lib/generated_plugin_registrant.dart"
-  strong-mode:
-    implicit-casts: false
-    implicit-dynamic: false
-  errors:
-    included_file_warning: ignore
-    missing_required_param: error
-    missing_return: error
-    parameter_assignments: error
-
-linter:
-  rules:
-    prefer_double_quotes: false
-    unnecessary_final: false
-    always_specify_types: false
-    prefer_final_parameters: false
-    prefer_asserts_with_message: false
-    require_trailing_commas: false
-    public_member_api_docs: false
-    avoid_classes_with_only_static_members: false
-    always_put_control_body_on_new_line: false
-    always_use_package_imports: false
-    avoid_annotating_with_dynamic: false
-    avoid_redundant_argument_values: false
-    one_member_abstracts: false
-    flutter_style_todos: false
-    diagnostic_describe_all_properties: false
-    library_private_types_in_public_api: false
diff --git a/packages/go_router/example/lib/async_data.dart b/packages/go_router/example/lib/async_data.dart
index 1ab14c2..2a87a83 100644
--- a/packages/go_router/example/lib/async_data.dart
+++ b/packages/go_router/example/lib/async_data.dart
@@ -13,11 +13,16 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates a [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Async Data';
-  static final repo = Repository();
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Async Data';
+
+  /// Repository to query data from.
+  static final Repository repo = Repository();
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -26,21 +31,24 @@
         title: title,
       );
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const HomeScreen(),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            const HomeScreen(),
+        routes: <GoRoute>[
           GoRoute(
             path: 'family/:fid',
-            builder: (context, state) => FamilyScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreen(
               fid: state.params['fid']!,
             ),
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 path: 'person/:pid',
-                builder: (context, state) => PersonScreen(
+                builder: (BuildContext context, GoRouterState state) =>
+                    PersonScreen(
                   fid: state.params['fid']!,
                   pid: state.params['pid']!,
                 ),
@@ -53,7 +61,9 @@
   );
 }
 
+/// The home screen.
 class HomeScreen extends StatefulWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({Key? key}) : super(key: key);
 
   @override
@@ -82,7 +92,7 @@
   @override
   Widget build(BuildContext context) => FutureBuilder<List<Family>>(
         future: _future,
-        builder: (context, snapshot) {
+        builder: (BuildContext context, AsyncSnapshot<List<Family>> snapshot) {
           if (snapshot.connectionState == ConnectionState.waiting) {
             return Scaffold(
               appBar: AppBar(title: const Text('${App.title}: Loading...')),
@@ -98,14 +108,14 @@
           }
 
           assert(snapshot.hasData);
-          final families = snapshot.data!;
+          final List<Family> families = snapshot.data!;
           return Scaffold(
             appBar: AppBar(
               title: Text('${App.title}: ${families.length} families'),
             ),
             body: ListView(
-              children: [
-                for (final f in families)
+              children: <Widget>[
+                for (final Family f in families)
                   ListTile(
                     title: Text(f.name),
                     onTap: () => context.go('/family/${f.id}'),
@@ -117,8 +127,12 @@
       );
 }
 
+/// The family screen.
 class FamilyScreen extends StatefulWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({required this.fid, Key? key}) : super(key: key);
+
+  /// The id of the family.
   final String fid;
 
   @override
@@ -139,7 +153,9 @@
     super.didUpdateWidget(oldWidget);
 
     // refresh cached data
-    if (oldWidget.fid != widget.fid) _fetch();
+    if (oldWidget.fid != widget.fid) {
+      _fetch();
+    }
   }
 
   void _fetch() => _future = App.repo.getFamily(widget.fid);
@@ -147,7 +163,7 @@
   @override
   Widget build(BuildContext context) => FutureBuilder<Family>(
         future: _future,
-        builder: (context, snapshot) {
+        builder: (BuildContext context, AsyncSnapshot<Family> snapshot) {
           if (snapshot.connectionState == ConnectionState.waiting) {
             return Scaffold(
               appBar: AppBar(title: const Text('Loading...')),
@@ -163,12 +179,12 @@
           }
 
           assert(snapshot.hasData);
-          final family = snapshot.data!;
+          final Family family = snapshot.data!;
           return Scaffold(
             appBar: AppBar(title: Text(family.name)),
             body: ListView(
-              children: [
-                for (final p in family.people)
+              children: <Widget>[
+                for (final Person p in family.people)
                   ListTile(
                     title: Text(p.name),
                     onTap: () => context.go(
@@ -182,11 +198,16 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatefulWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.fid, required this.pid, Key? key})
       : super(key: key);
 
+  /// The id of family the person is in.
   final String fid;
+
+  /// The id of the person.
   final String pid;
 
   @override
@@ -207,7 +228,9 @@
     super.didUpdateWidget(oldWidget);
 
     // refresh cached data
-    if (oldWidget.fid != widget.fid || oldWidget.pid != widget.pid) _fetch();
+    if (oldWidget.fid != widget.fid || oldWidget.pid != widget.pid) {
+      _fetch();
+    }
   }
 
   void _fetch() => _future = App.repo.getPerson(widget.fid, widget.pid);
@@ -215,7 +238,7 @@
   @override
   Widget build(BuildContext context) => FutureBuilder<FamilyPerson>(
         future: _future,
-        builder: (context, snapshot) {
+        builder: (BuildContext context, AsyncSnapshot<FamilyPerson> snapshot) {
           if (snapshot.connectionState == ConnectionState.waiting) {
             return Scaffold(
               appBar: AppBar(title: const Text('Loading...')),
@@ -231,7 +254,7 @@
           }
 
           assert(snapshot.hasData);
-          final famper = snapshot.data!;
+          final FamilyPerson famper = snapshot.data!;
           return Scaffold(
             appBar: AppBar(title: Text(famper.person.name)),
             body: Text(
@@ -243,17 +266,21 @@
       );
 }
 
+/// The Error page.
 class SnapshotError extends StatelessWidget {
+  /// Creates an error page.
   SnapshotError(Object error, {Key? key})
       : error = error is Exception ? error : Exception(error),
         super(key: key);
+
+  /// The error.
   final Exception error;
 
   @override
   Widget build(BuildContext context) => Center(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
-          children: [
+          children: <Widget>[
             SelectableText(error.toString()),
             TextButton(
               onPressed: () => context.go('/'),
diff --git a/packages/go_router/example/lib/books/main.dart b/packages/go_router/example/lib/books/main.dart
index f5af909..7f20594 100644
--- a/packages/go_router/example/lib/books/main.dart
+++ b/packages/go_router/example/lib/books/main.dart
@@ -7,6 +7,8 @@
 import 'package:go_router/go_router.dart';
 
 import 'src/auth.dart';
+import 'src/data/author.dart';
+import 'src/data/book.dart';
 import 'src/data/library.dart';
 import 'src/screens/author_details.dart';
 import 'src/screens/authors.dart';
@@ -18,10 +20,12 @@
 
 void main() => runApp(Bookstore());
 
+/// The book store view.
 class Bookstore extends StatelessWidget {
+  /// Creates a [Bookstore].
   Bookstore({Key? key}) : super(key: key);
 
-  final _scaffoldKey = const ValueKey<String>('App scaffold');
+  final ValueKey<String> _scaffoldKey = const ValueKey<String>('App scaffold');
 
   @override
   Widget build(BuildContext context) => BookstoreAuthScope(
@@ -32,20 +36,21 @@
         ),
       );
 
-  final _auth = BookstoreAuth();
+  final BookstoreAuth _auth = BookstoreAuth();
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
         redirect: (_) => '/books',
       ),
       GoRoute(
         path: '/signin',
-        pageBuilder: (context, state) => FadeTransitionPage(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            FadeTransitionPage(
           key: state.pageKey,
           child: SignInScreen(
-            onSignIn: (credentials) {
+            onSignIn: (Credentials credentials) {
               BookstoreAuthScope.of(context)
                   .signIn(credentials.username, credentials.password);
             },
@@ -58,24 +63,26 @@
       ),
       GoRoute(
         path: '/book/:bookId',
-        redirect: (state) => '/books/all/${state.params['bookId']}',
+        redirect: (GoRouterState state) =>
+            '/books/all/${state.params['bookId']}',
       ),
       GoRoute(
         path: '/books/:kind(new|all|popular)',
-        pageBuilder: (context, state) => FadeTransitionPage(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            FadeTransitionPage(
           key: _scaffoldKey,
           child: BookstoreScaffold(
             selectedTab: ScaffoldTab.books,
             child: BooksScreen(state.params['kind']!),
           ),
         ),
-        routes: [
+        routes: <GoRoute>[
           GoRoute(
             path: ':bookId',
-            builder: (context, state) {
-              final bookId = state.params['bookId']!;
-              final selectedBook = libraryInstance.allBooks
-                  .firstWhereOrNull((b) => b.id.toString() == bookId);
+            builder: (BuildContext context, GoRouterState state) {
+              final String bookId = state.params['bookId']!;
+              final Book? selectedBook = libraryInstance.allBooks
+                  .firstWhereOrNull((Book b) => b.id.toString() == bookId);
 
               return BookDetailsScreen(book: selectedBook);
             },
@@ -84,24 +91,26 @@
       ),
       GoRoute(
         path: '/author/:authorId',
-        redirect: (state) => '/authors/${state.params['authorId']}',
+        redirect: (GoRouterState state) =>
+            '/authors/${state.params['authorId']}',
       ),
       GoRoute(
         path: '/authors',
-        pageBuilder: (context, state) => FadeTransitionPage(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            FadeTransitionPage(
           key: _scaffoldKey,
           child: const BookstoreScaffold(
             selectedTab: ScaffoldTab.authors,
             child: AuthorsScreen(),
           ),
         ),
-        routes: [
+        routes: <GoRoute>[
           GoRoute(
             path: ':authorId',
-            builder: (context, state) {
-              final authorId = int.parse(state.params['authorId']!);
-              final selectedAuthor = libraryInstance.allAuthors
-                  .firstWhereOrNull((a) => a.id == authorId);
+            builder: (BuildContext context, GoRouterState state) {
+              final int authorId = int.parse(state.params['authorId']!);
+              final Author? selectedAuthor = libraryInstance.allAuthors
+                  .firstWhereOrNull((Author a) => a.id == authorId);
 
               return AuthorDetailsScreen(author: selectedAuthor);
             },
@@ -110,7 +119,8 @@
       ),
       GoRoute(
         path: '/settings',
-        pageBuilder: (context, state) => FadeTransitionPage(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            FadeTransitionPage(
           key: _scaffoldKey,
           child: const BookstoreScaffold(
             selectedTab: ScaffoldTab.settings,
@@ -125,8 +135,8 @@
   );
 
   String? _guard(GoRouterState state) {
-    final signedIn = _auth.signedIn;
-    final signingIn = state.subloc == '/signin';
+    final bool signedIn = _auth.signedIn;
+    final bool signingIn = state.subloc == '/signin';
 
     // Go to /signin if the user is not signed in
     if (!signedIn && !signingIn) {
@@ -142,17 +152,23 @@
   }
 }
 
+/// A page that fades in an out.
 class FadeTransitionPage extends CustomTransitionPage<void> {
+  /// Creates a [FadeTransitionPage].
   FadeTransitionPage({
     required LocalKey key,
     required Widget child,
   }) : super(
             key: key,
-            transitionsBuilder: (c, animation, a2, child) => FadeTransition(
+            transitionsBuilder: (BuildContext context,
+                    Animation<double> animation,
+                    Animation<double> secondaryAnimation,
+                    Widget child) =>
+                FadeTransition(
                   opacity: animation.drive(_curveTween),
                   child: child,
                 ),
             child: child);
 
-  static final _curveTween = CurveTween(curve: Curves.easeIn);
+  static final CurveTween _curveTween = CurveTween(curve: Curves.easeIn);
 }
diff --git a/packages/go_router/example/lib/books/src/auth.dart b/packages/go_router/example/lib/books/src/auth.dart
index f848149..2b71e4c 100644
--- a/packages/go_router/example/lib/books/src/auth.dart
+++ b/packages/go_router/example/lib/books/src/auth.dart
@@ -8,8 +8,10 @@
 class BookstoreAuth extends ChangeNotifier {
   bool _signedIn = false;
 
+  /// Whether user has signed in.
   bool get signedIn => _signedIn;
 
+  /// Signs out the current user.
   Future<void> signOut() async {
     await Future<void>.delayed(const Duration(milliseconds: 200));
     // Sign out.
@@ -17,6 +19,7 @@
     notifyListeners();
   }
 
+  /// Signs in a user.
   Future<bool> signIn(String username, String password) async {
     await Future<void>.delayed(const Duration(milliseconds: 200));
 
@@ -27,13 +30,16 @@
   }
 }
 
+/// An inherited notifier to host [BookstoreAuth] for the subtree.
 class BookstoreAuthScope extends InheritedNotifier<BookstoreAuth> {
+  /// Creates a [BookstoreAuthScope].
   const BookstoreAuthScope({
     required BookstoreAuth notifier,
     required Widget child,
     Key? key,
   }) : super(key: key, notifier: notifier, child: child);
 
+  /// Gets the [BookstoreAuth] above the context.
   static BookstoreAuth of(BuildContext context) => context
       .dependOnInheritedWidgetOfExactType<BookstoreAuthScope>()!
       .notifier!;
diff --git a/packages/go_router/example/lib/books/src/data/author.dart b/packages/go_router/example/lib/books/src/data/author.dart
index 51138ea..b58db11 100644
--- a/packages/go_router/example/lib/books/src/data/author.dart
+++ b/packages/go_router/example/lib/books/src/data/author.dart
@@ -4,13 +4,20 @@
 
 import 'book.dart';
 
+/// Author data class.
 class Author {
+  /// Creates an author data object.
   Author({
     required this.id,
     required this.name,
   });
 
+  /// The id of the author.
   final int id;
+
+  /// The name of the author.
   final String name;
+
+  /// The books of the author.
   final List<Book> books = <Book>[];
 }
diff --git a/packages/go_router/example/lib/books/src/data/book.dart b/packages/go_router/example/lib/books/src/data/book.dart
index 036bbaa..cd2c94f 100644
--- a/packages/go_router/example/lib/books/src/data/book.dart
+++ b/packages/go_router/example/lib/books/src/data/book.dart
@@ -4,7 +4,9 @@
 
 import 'author.dart';
 
+/// Book data class.
 class Book {
+  /// Creates a book data object.
   Book({
     required this.id,
     required this.title,
@@ -13,9 +15,18 @@
     required this.author,
   });
 
+  /// The id of the book.
   final int id;
+
+  /// The title of the book.
   final String title;
+
+  /// The author of the book.
   final Author author;
+
+  /// Whether the book is popular.
   final bool isPopular;
+
+  /// Whether the book is new.
   final bool isNew;
 }
diff --git a/packages/go_router/example/lib/books/src/data/library.dart b/packages/go_router/example/lib/books/src/data/library.dart
index d58e5e2..075b825 100644
--- a/packages/go_router/example/lib/books/src/data/library.dart
+++ b/packages/go_router/example/lib/books/src/data/library.dart
@@ -5,7 +5,8 @@
 import 'author.dart';
 import 'book.dart';
 
-final libraryInstance = Library()
+/// Library data mock.
+final Library libraryInstance = Library()
   ..addBook(
       title: 'Left Hand of Darkness',
       authorName: 'Ursula K. Le Guin',
@@ -27,26 +28,31 @@
       isPopular: false,
       isNew: false);
 
+/// A library that contains books and authors.
 class Library {
-  final List<Book> allBooks = [];
-  final List<Author> allAuthors = [];
+  /// The books in the library.
+  final List<Book> allBooks = <Book>[];
 
+  /// The authors in the library.
+  final List<Author> allAuthors = <Author>[];
+
+  /// Adds a book into the library.
   void addBook({
     required String title,
     required String authorName,
     required bool isPopular,
     required bool isNew,
   }) {
-    final author = allAuthors.firstWhere(
-      (author) => author.name == authorName,
+    final Author author = allAuthors.firstWhere(
+      (Author author) => author.name == authorName,
       orElse: () {
-        final value = Author(id: allAuthors.length, name: authorName);
+        final Author value = Author(id: allAuthors.length, name: authorName);
         allAuthors.add(value);
         return value;
       },
     );
 
-    final book = Book(
+    final Book book = Book(
       id: allBooks.length,
       title: title,
       isPopular: isPopular,
@@ -58,11 +64,13 @@
     allBooks.add(book);
   }
 
-  List<Book> get popularBooks => [
-        ...allBooks.where((book) => book.isPopular),
+  /// The list of popular books in the library.
+  List<Book> get popularBooks => <Book>[
+        ...allBooks.where((Book book) => book.isPopular),
       ];
 
-  List<Book> get newBooks => [
-        ...allBooks.where((book) => book.isNew),
+  /// The list of new books in the library.
+  List<Book> get newBooks => <Book>[
+        ...allBooks.where((Book book) => book.isNew),
       ];
 }
diff --git a/packages/go_router/example/lib/books/src/screens/author_details.dart b/packages/go_router/example/lib/books/src/screens/author_details.dart
index 0cde5a2..d03ae63 100644
--- a/packages/go_router/example/lib/books/src/screens/author_details.dart
+++ b/packages/go_router/example/lib/books/src/screens/author_details.dart
@@ -8,12 +8,15 @@
 import '../data.dart';
 import '../widgets/book_list.dart';
 
+/// The author detail screen.
 class AuthorDetailsScreen extends StatelessWidget {
+  /// Creates an author detail screen.
   const AuthorDetailsScreen({
     required this.author,
     Key? key,
   }) : super(key: key);
 
+  /// The author to be displayed.
   final Author? author;
 
   @override
@@ -31,11 +34,11 @@
       ),
       body: Center(
         child: Column(
-          children: [
+          children: <Widget>[
             Expanded(
               child: BookList(
                 books: author!.books,
-                onTap: (book) => context.go('/book/${book.id}'),
+                onTap: (Book book) => context.go('/book/${book.id}'),
               ),
             ),
           ],
diff --git a/packages/go_router/example/lib/books/src/screens/authors.dart b/packages/go_router/example/lib/books/src/screens/authors.dart
index 9726996..893a3c0 100644
--- a/packages/go_router/example/lib/books/src/screens/authors.dart
+++ b/packages/go_router/example/lib/books/src/screens/authors.dart
@@ -5,13 +5,16 @@
 import 'package:flutter/material.dart';
 import 'package:go_router/go_router.dart';
 
-import '../data/library.dart';
+import '../data.dart';
 import '../widgets/author_list.dart';
 
+/// A screen that displays a list of authors.
 class AuthorsScreen extends StatelessWidget {
+  /// Creates an [AuthorsScreen].
   const AuthorsScreen({Key? key}) : super(key: key);
 
-  static const title = 'Authors';
+  /// The title of the screen.
+  static const String title = 'Authors';
 
   @override
   Widget build(BuildContext context) => Scaffold(
@@ -20,7 +23,7 @@
         ),
         body: AuthorList(
           authors: libraryInstance.allAuthors,
-          onTap: (author) {
+          onTap: (Author author) {
             context.go('/author/${author.id}');
           },
         ),
diff --git a/packages/go_router/example/lib/books/src/screens/book_details.dart b/packages/go_router/example/lib/books/src/screens/book_details.dart
index 0bdce99..d26ff71 100644
--- a/packages/go_router/example/lib/books/src/screens/book_details.dart
+++ b/packages/go_router/example/lib/books/src/screens/book_details.dart
@@ -9,12 +9,15 @@
 import '../data.dart';
 import 'author_details.dart';
 
+/// A screen to display book details.
 class BookDetailsScreen extends StatelessWidget {
+  /// Creates a [BookDetailsScreen].
   const BookDetailsScreen({
     Key? key,
     this.book,
   }) : super(key: key);
 
+  /// The book to be displayed.
   final Book? book;
 
   @override
@@ -32,7 +35,7 @@
       ),
       body: Center(
         child: Column(
-          children: [
+          children: <Widget>[
             Text(
               book!.title,
               style: Theme.of(context).textTheme.headline4,
@@ -45,7 +48,7 @@
               onPressed: () {
                 Navigator.of(context).push<void>(
                   MaterialPageRoute<void>(
-                    builder: (context) =>
+                    builder: (BuildContext context) =>
                         AuthorDetailsScreen(author: book!.author),
                   ),
                 );
@@ -54,7 +57,8 @@
             ),
             Link(
               uri: Uri.parse('/author/${book!.author.id}'),
-              builder: (context, followLink) => TextButton(
+              builder: (BuildContext context, FollowLink? followLink) =>
+                  TextButton(
                 onPressed: followLink,
                 child: const Text('View author (Link)'),
               ),
diff --git a/packages/go_router/example/lib/books/src/screens/books.dart b/packages/go_router/example/lib/books/src/screens/books.dart
index 156d140..76f77b4 100644
--- a/packages/go_router/example/lib/books/src/screens/books.dart
+++ b/packages/go_router/example/lib/books/src/screens/books.dart
@@ -8,9 +8,12 @@
 import '../data.dart';
 import '../widgets/book_list.dart';
 
+/// A screen that displays a list of books.
 class BooksScreen extends StatefulWidget {
+  /// Creates a [BooksScreen].
   const BooksScreen(this.kind, {Key? key}) : super(key: key);
 
+  /// Which tab to display.
   final String kind;
 
   @override
@@ -59,7 +62,7 @@
           bottom: TabBar(
             controller: _tabController,
             onTap: _handleTabTapped,
-            tabs: const [
+            tabs: const <Tab>[
               Tab(
                 text: 'Popular',
                 icon: Icon(Icons.people),
@@ -77,7 +80,7 @@
         ),
         body: TabBarView(
           controller: _tabController,
-          children: [
+          children: <Widget>[
             BookList(
               books: libraryInstance.popularBooks,
               onTap: _handleBookTapped,
diff --git a/packages/go_router/example/lib/books/src/screens/scaffold.dart b/packages/go_router/example/lib/books/src/screens/scaffold.dart
index ce67e37..a3f8134 100644
--- a/packages/go_router/example/lib/books/src/screens/scaffold.dart
+++ b/packages/go_router/example/lib/books/src/screens/scaffold.dart
@@ -7,16 +7,31 @@
 
 import 'package:go_router/go_router.dart';
 
-enum ScaffoldTab { books, authors, settings }
+/// The enum for scaffold tab
+enum ScaffoldTab {
+  /// The books tab.
+  books,
 
+  /// The authors tab.
+  authors,
+
+  /// The settings tab.
+  settings
+}
+
+/// The scaffold for the book store.
 class BookstoreScaffold extends StatelessWidget {
+  /// Creates a [BookstoreScaffold].
   const BookstoreScaffold({
     required this.selectedTab,
     required this.child,
     Key? key,
   }) : super(key: key);
 
+  /// Which tab of the scaffold to display.
   final ScaffoldTab selectedTab;
+
+  /// The scaffold body.
   final Widget child;
 
   @override
@@ -24,7 +39,7 @@
         body: AdaptiveNavigationScaffold(
           selectedIndex: selectedTab.index,
           body: child,
-          onDestinationSelected: (idx) {
+          onDestinationSelected: (int idx) {
             switch (ScaffoldTab.values[idx]) {
               case ScaffoldTab.books:
                 context.go('/books');
@@ -37,7 +52,7 @@
                 break;
             }
           },
-          destinations: const [
+          destinations: const <AdaptiveScaffoldDestination>[
             AdaptiveScaffoldDestination(
               title: 'Books',
               icon: Icons.book,
diff --git a/packages/go_router/example/lib/books/src/screens/settings.dart b/packages/go_router/example/lib/books/src/screens/settings.dart
index d6dcced..5634bc2 100644
--- a/packages/go_router/example/lib/books/src/screens/settings.dart
+++ b/packages/go_router/example/lib/books/src/screens/settings.dart
@@ -8,7 +8,9 @@
 
 import '../auth.dart';
 
+/// The settings screen.
 class SettingsScreen extends StatefulWidget {
+  /// Creates a [SettingsScreen].
   const SettingsScreen({Key? key}) : super(key: key);
 
   @override
@@ -37,15 +39,17 @@
       );
 }
 
+/// The content of a [SettingsScreen].
 class SettingsContent extends StatelessWidget {
+  /// Creates a [SettingsContent].
   const SettingsContent({
     Key? key,
   }) : super(key: key);
 
   @override
   Widget build(BuildContext context) => Column(
-        children: [
-          ...[
+        children: <Widget>[
+          ...<Widget>[
             Text(
               'Settings',
               style: Theme.of(context).textTheme.headline4,
@@ -58,7 +62,8 @@
             ),
             Link(
               uri: Uri.parse('/book/0'),
-              builder: (context, followLink) => TextButton(
+              builder: (BuildContext context, FollowLink? followLink) =>
+                  TextButton(
                 onPressed: followLink,
                 child: const Text('Go directly to /book/0 (Link)'),
               ),
@@ -69,11 +74,12 @@
               },
               child: const Text('Go directly to /book/0 (GoRouter)'),
             ),
-          ].map((w) => Padding(padding: const EdgeInsets.all(8), child: w)),
+          ].map<Widget>((Widget w) =>
+              Padding(padding: const EdgeInsets.all(8), child: w)),
           TextButton(
             onPressed: () => showDialog<String>(
               context: context,
-              builder: (context) => AlertDialog(
+              builder: (BuildContext context) => AlertDialog(
                 title: const Text('Alert!'),
                 content: const Text('The alert description goes here.'),
                 actions: <Widget>[
diff --git a/packages/go_router/example/lib/books/src/screens/sign_in.dart b/packages/go_router/example/lib/books/src/screens/sign_in.dart
index 56b478b..808bc15 100644
--- a/packages/go_router/example/lib/books/src/screens/sign_in.dart
+++ b/packages/go_router/example/lib/books/src/screens/sign_in.dart
@@ -4,19 +4,27 @@
 
 import 'package:flutter/material.dart';
 
+/// Credential data class.
 class Credentials {
+  /// Creates a credential data object.
   Credentials(this.username, this.password);
 
+  /// The username of the credentials.
   final String username;
+
+  /// The password of the credentials.
   final String password;
 }
 
+/// The sign-in screen.
 class SignInScreen extends StatefulWidget {
+  /// Creates a sign-in screen.
   const SignInScreen({
     required this.onSignIn,
     Key? key,
   }) : super(key: key);
 
+  /// Called when users sign in with [Credentials].
   final ValueChanged<Credentials> onSignIn;
 
   @override
@@ -24,8 +32,8 @@
 }
 
 class _SignInScreenState extends State<SignInScreen> {
-  final _usernameController = TextEditingController();
-  final _passwordController = TextEditingController();
+  final TextEditingController _usernameController = TextEditingController();
+  final TextEditingController _passwordController = TextEditingController();
 
   @override
   Widget build(BuildContext context) => Scaffold(
@@ -37,7 +45,7 @@
               child: Column(
                 mainAxisAlignment: MainAxisAlignment.center,
                 mainAxisSize: MainAxisSize.min,
-                children: [
+                children: <Widget>[
                   Text('Sign in', style: Theme.of(context).textTheme.headline4),
                   TextField(
                     decoration: const InputDecoration(labelText: 'Username'),
diff --git a/packages/go_router/example/lib/books/src/widgets/author_list.dart b/packages/go_router/example/lib/books/src/widgets/author_list.dart
index 91dd163..d749631 100644
--- a/packages/go_router/example/lib/books/src/widgets/author_list.dart
+++ b/packages/go_router/example/lib/books/src/widgets/author_list.dart
@@ -6,20 +6,25 @@
 
 import '../data.dart';
 
+/// The author list view.
 class AuthorList extends StatelessWidget {
+  /// Creates an [AuthorList].
   const AuthorList({
     required this.authors,
     this.onTap,
     Key? key,
   }) : super(key: key);
 
+  /// The list of authors to be shown.
   final List<Author> authors;
+
+  /// Called when the user taps an author.
   final ValueChanged<Author>? onTap;
 
   @override
   Widget build(BuildContext context) => ListView.builder(
         itemCount: authors.length,
-        itemBuilder: (context, index) => ListTile(
+        itemBuilder: (BuildContext context, int index) => ListTile(
           title: Text(
             authors[index].name,
           ),
diff --git a/packages/go_router/example/lib/books/src/widgets/book_list.dart b/packages/go_router/example/lib/books/src/widgets/book_list.dart
index 7f07206..af37e15 100644
--- a/packages/go_router/example/lib/books/src/widgets/book_list.dart
+++ b/packages/go_router/example/lib/books/src/widgets/book_list.dart
@@ -6,20 +6,25 @@
 
 import '../data.dart';
 
+/// The book list view.
 class BookList extends StatelessWidget {
+  /// Creates an [BookList].
   const BookList({
     required this.books,
     this.onTap,
     Key? key,
   }) : super(key: key);
 
+  /// The list of books to be displayed.
   final List<Book> books;
+
+  /// Called when the user taps a book.
   final ValueChanged<Book>? onTap;
 
   @override
   Widget build(BuildContext context) => ListView.builder(
         itemCount: books.length,
-        itemBuilder: (context, index) => ListTile(
+        itemBuilder: (BuildContext context, int index) => ListTile(
           title: Text(
             books[index].title,
           ),
diff --git a/packages/go_router/example/lib/cupertino.dart b/packages/go_router/example/lib/cupertino.dart
index 77fd28d..3511295 100644
--- a/packages/go_router/example/lib/cupertino.dart
+++ b/packages/go_router/example/lib/cupertino.dart
@@ -7,10 +7,13 @@
 
 void main() => runApp(App());
 
+/// The main app
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Cupertino App';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Cupertino App';
 
   @override
   Widget build(BuildContext context) => CupertinoApp.router(
@@ -19,21 +22,25 @@
         title: title,
       );
 
-  final _router = GoRouter(
-    routes: [
+  final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page2Screen(),
       ),
     ],
   );
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -42,7 +49,7 @@
         child: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               CupertinoButton(
                 onPressed: () => context.go('/page2'),
                 child: const Text('Go to page 2'),
@@ -53,7 +60,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -62,7 +71,7 @@
         child: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               CupertinoButton(
                 onPressed: () => context.go('/'),
                 child: const Text('Go to home page'),
diff --git a/packages/go_router/example/lib/error_screen.dart b/packages/go_router/example/lib/error_screen.dart
index b872fed..984441b 100644
--- a/packages/go_router/example/lib/error_screen.dart
+++ b/packages/go_router/example/lib/error_screen.dart
@@ -7,10 +7,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Custom Error Screen';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Custom Error Screen';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -19,22 +22,27 @@
         title: title,
       );
 
-  final _router = GoRouter(
-    routes: [
+  final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page2Screen(),
       ),
     ],
-    errorBuilder: (context, state) => ErrorScreen(state.error!),
+    errorBuilder: (BuildContext context, GoRouterState state) =>
+        ErrorScreen(state.error!),
   );
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -43,7 +51,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/page2'),
                 child: const Text('Go to page 2'),
@@ -54,7 +62,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -63,7 +73,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/'),
                 child: const Text('Go to home page'),
@@ -74,8 +84,12 @@
       );
 }
 
+/// The screen of the error page
 class ErrorScreen extends StatelessWidget {
+  /// Creates an [ErrorScreen].
   const ErrorScreen(this.error, {Key? key}) : super(key: key);
+
+  /// The error to display.
   final Exception error;
 
   @override
@@ -84,7 +98,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               SelectableText(error.toString()),
               TextButton(
                 onPressed: () => context.go('/'),
diff --git a/packages/go_router/example/lib/extra_param.dart b/packages/go_router/example/lib/extra_param.dart
index 660a49b..5e9141a 100644
--- a/packages/go_router/example/lib/extra_param.dart
+++ b/packages/go_router/example/lib/extra_param.dart
@@ -10,14 +10,18 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Extra Parameter';
-  static const alertOnWeb = true;
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Extra Parameter';
+
+  static const bool _alertOnWeb = true;
 
   @override
-  Widget build(BuildContext context) => alertOnWeb && kIsWeb
+  Widget build(BuildContext context) => _alertOnWeb && kIsWeb
       ? const MaterialApp(
           title: title,
           home: NoExtraParamOnWebScreen(),
@@ -28,29 +32,32 @@
           title: title,
         );
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         name: 'home',
         path: '/',
-        builder: (context, state) => HomeScreen(families: Families.data),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            HomeScreen(families: Families.data),
+        routes: <GoRoute>[
           GoRoute(
             name: 'family',
             path: 'family',
-            builder: (context, state) {
-              final params = state.extra! as Map<String, Object>;
-              final family = params['family']! as Family;
+            builder: (BuildContext context, GoRouterState state) {
+              final Map<String, Object> params =
+                  state.extra! as Map<String, Object>;
+              final Family family = params['family']! as Family;
               return FamilyScreen(family: family);
             },
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 name: 'person',
                 path: 'person',
-                builder: (context, state) {
-                  final params = state.extra! as Map<String, Object>;
-                  final family = params['family']! as Family;
-                  final person = params['person']! as Person;
+                builder: (BuildContext context, GoRouterState state) {
+                  final Map<String, Object> params =
+                      state.extra! as Map<String, Object>;
+                  final Family family = params['family']! as Family;
+                  final Person person = params['person']! as Person;
                   return PersonScreen(family: family, person: person);
                 },
               ),
@@ -62,40 +69,49 @@
   );
 }
 
+/// The home screen that shows a list of families.
 class HomeScreen extends StatelessWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({required this.families, Key? key}) : super(key: key);
+
+  /// The list of families.
   final List<Family> families;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: const Text(App.title)),
         body: ListView(
-          children: [
-            for (final f in families)
+          children: <Widget>[
+            for (final Family f in families)
               ListTile(
                 title: Text(f.name),
-                onTap: () => context.goNamed('family', extra: {'family': f}),
+                onTap: () => context
+                    .goNamed('family', extra: <String, Object?>{'family': f}),
               )
           ],
         ),
       );
 }
 
+/// The screen that shows a list of persons in a family.
 class FamilyScreen extends StatelessWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: Text(family.name)),
         body: ListView(
-          children: [
-            for (final p in family.people)
+          children: <Widget>[
+            for (final Person p in family.people)
               ListTile(
                 title: Text(p.name),
                 onTap: () => context.go(
                   context.namedLocation('person'),
-                  extra: {'family': family, 'person': p},
+                  extra: <String, Object>{'family': family, 'person': p},
                 ),
               ),
           ],
@@ -103,11 +119,16 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.family, required this.person, Key? key})
       : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
@@ -117,7 +138,9 @@
       );
 }
 
+/// A screen that explains this example does not work on web platform.
 class NoExtraParamOnWebScreen extends StatelessWidget {
+  /// Creates a [NoExtraParamOnWebScreen].
   const NoExtraParamOnWebScreen({Key? key}) : super(key: key);
 
   @override
@@ -126,7 +149,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: const [
+            children: const <Widget>[
               Text("The `extra` param doesn't mix with the web:"),
               Text("There's no support for the brower's Back button or"
                   ' deep linking'),
diff --git a/packages/go_router/example/lib/init_loc.dart b/packages/go_router/example/lib/init_loc.dart
index 07442ff..4bef656 100644
--- a/packages/go_router/example/lib/init_loc.dart
+++ b/packages/go_router/example/lib/init_loc.dart
@@ -7,10 +7,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Initial Location';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Initial Location';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -19,26 +22,31 @@
         title: title,
       );
 
-  final _router = GoRouter(
+  final GoRouter _router = GoRouter(
     initialLocation: '/page3',
-    routes: [
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page2Screen(),
       ),
       GoRoute(
         path: '/page3',
-        builder: (context, state) => const Page3Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page3Screen(),
       ),
     ],
   );
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -47,7 +55,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/page2'),
                 child: const Text('Go to page 2'),
@@ -58,7 +66,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -67,7 +77,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/'),
                 child: const Text('Go to home page'),
@@ -78,7 +88,9 @@
       );
 }
 
+/// The screen of the third page.
 class Page3Screen extends StatelessWidget {
+  /// Creates a [Page3Screen].
   const Page3Screen({Key? key}) : super(key: key);
 
   @override
@@ -87,7 +99,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/page2'),
                 child: const Text('Go to page 2'),
diff --git a/packages/go_router/example/lib/loading_page.dart b/packages/go_router/example/lib/loading_page.dart
index d6d4bb7..2afb21e 100644
--- a/packages/go_router/example/lib/loading_page.dart
+++ b/packages/go_router/example/lib/loading_page.dart
@@ -10,15 +10,21 @@
 
 void main() => runApp(App());
 
+/// The app state data class.
 class AppState extends ChangeNotifier {
+  /// Creates an [AppState].
   AppState() {
     loginInfo.addListener(loginChange);
     repo.addListener(notifyListeners);
   }
 
-  final loginInfo = LoginInfo2();
-  final repo = ValueNotifier<Repository2?>(null);
+  /// The login status.
+  final LoginInfo2 loginInfo = LoginInfo2();
 
+  /// The repository to query data from.
+  final ValueNotifier<Repository2?> repo = ValueNotifier<Repository2?>(null);
+
+  /// Called when login status changed.
   Future<void> loginChange() async {
     notifyListeners();
 
@@ -35,15 +41,19 @@
   }
 }
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Loading Page';
-  final appState = AppState();
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Loading Page';
+
+  final AppState _appState = AppState();
 
   @override
   Widget build(BuildContext context) => ChangeNotifierProvider<AppState>.value(
-        value: appState,
+        value: _appState,
         child: MaterialApp.router(
           routeInformationParser: _router.routeInformationParser,
           routerDelegate: _router.routerDelegate,
@@ -52,29 +62,34 @@
         ),
       );
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/login',
-        builder: (context, state) => const LoginScreen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const LoginScreen(),
       ),
       GoRoute(
         path: '/loading',
-        builder: (context, state) => const LoadingScreen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const LoadingScreen(),
       ),
       GoRoute(
         path: '/',
-        builder: (context, state) => const HomeScreen(),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            const HomeScreen(),
+        routes: <GoRoute>[
           GoRoute(
             path: 'family/:fid',
-            builder: (context, state) => FamilyScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreen(
               fid: state.params['fid']!,
             ),
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 path: 'person/:pid',
-                builder: (context, state) => PersonScreen(
+                builder: (BuildContext context, GoRouterState state) =>
+                    PersonScreen(
                   fid: state.params['fid']!,
                   pid: state.params['pid']!,
                 ),
@@ -84,46 +99,56 @@
         ],
       ),
     ],
-    redirect: (state) {
+    redirect: (GoRouterState state) {
       // if the user is not logged in, they need to login
-      final loggedIn = appState.loginInfo.loggedIn;
-      final loggingIn = state.subloc == '/login';
-      final subloc = state.subloc;
-      final fromp1 = subloc == '/' ? '' : '?from=$subloc';
-      if (!loggedIn) return loggingIn ? null : '/login$fromp1';
+      final bool loggedIn = _appState.loginInfo.loggedIn;
+      final bool loggingIn = state.subloc == '/login';
+      final String subloc = state.subloc;
+      final String fromp1 = subloc == '/' ? '' : '?from=$subloc';
+      if (!loggedIn) {
+        return loggingIn ? null : '/login$fromp1';
+      }
 
       // if the user is logged in but the repository is not loaded, they need to
       // wait while it's loaded
-      final loaded = appState.repo.value != null;
-      final loading = state.subloc == '/loading';
-      final from = state.queryParams['from'];
-      final fromp2 = from == null ? '' : '?from=$from';
-      if (!loaded) return loading ? null : '/loading$fromp2';
+      final bool loaded = _appState.repo.value != null;
+      final bool loading = state.subloc == '/loading';
+      final String? from = state.queryParams['from'];
+      final String fromp2 = from == null ? '' : '?from=$from';
+      if (!loaded) {
+        return loading ? null : '/loading$fromp2';
+      }
 
       // if the user is logged in and the repository is loaded, send them where
       // they were going before (or home if they weren't going anywhere)
-      if (loggingIn || loading) return from ?? '/';
+      if (loggingIn || loading) {
+        return from ?? '/';
+      }
 
       // no need to redirect at all
       return null;
     },
-    refreshListenable: appState,
-    navigatorBuilder: (context, state, child) =>
-        appState.loginInfo.loggedIn ? AuthOverlay(child: child) : child,
+    refreshListenable: _appState,
+    navigatorBuilder:
+        (BuildContext context, GoRouterState state, Widget child) =>
+            _appState.loginInfo.loggedIn ? AuthOverlay(child: child) : child,
   );
 }
 
+/// A simple class for placing an exit button on top of all screens.
 class AuthOverlay extends StatelessWidget {
+  /// Creates an [AuthOverlay].
   const AuthOverlay({
     required this.child,
     Key? key,
   }) : super(key: key);
 
+  /// The child subtree.
   final Widget child;
 
   @override
   Widget build(BuildContext context) => Stack(
-        children: [
+        children: <Widget>[
           child,
           Positioned(
             top: 90,
@@ -142,7 +167,9 @@
       );
 }
 
+/// The login screen.
 class LoginScreen extends StatefulWidget {
+  /// Creates a [LoginScreen].
   const LoginScreen({Key? key}) : super(key: key);
 
   @override
@@ -156,7 +183,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () async {
                   // ignore: unawaited_futures
@@ -170,9 +197,10 @@
       );
 }
 
+/// The loading screen.
 class LoadingScreen extends StatelessWidget {
-  const LoadingScreen({this.from, Key? key}) : super(key: key);
-  final String? from;
+  /// Creates a [LoadingScreen].
+  const LoadingScreen({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) => Scaffold(
@@ -180,7 +208,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: const [
+            children: const <Widget>[
               CircularProgressIndicator(),
               Text('loading repository...'),
             ],
@@ -189,7 +217,9 @@
       );
 }
 
+/// The home screen.
 class HomeScreen extends StatefulWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({Key? key}) : super(key: key);
 
   @override
@@ -219,13 +249,13 @@
   @override
   Widget build(BuildContext context) => MyFutureBuilder<List<Family>>(
         future: _future,
-        builder: (context, families) => Scaffold(
+        builder: (BuildContext context, List<Family> families) => Scaffold(
           appBar: AppBar(
             title: Text('${App.title}: ${families.length} families'),
           ),
           body: ListView(
-            children: [
-              for (final f in families)
+            children: <Widget>[
+              for (final Family f in families)
                 ListTile(
                   title: Text(f.name),
                   onTap: () => context.go('/family/${f.id}'),
@@ -236,8 +266,12 @@
       );
 }
 
+/// The family screen.
 class FamilyScreen extends StatefulWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({required this.fid, Key? key}) : super(key: key);
+
+  /// The family id.
   final String fid;
 
   @override
@@ -258,7 +292,9 @@
     super.didUpdateWidget(oldWidget);
 
     // refresh cached data
-    if (oldWidget.fid != widget.fid) _fetch();
+    if (oldWidget.fid != widget.fid) {
+      _fetch();
+    }
   }
 
   void _fetch() => _future = _repo.getFamily(widget.fid);
@@ -267,11 +303,11 @@
   @override
   Widget build(BuildContext context) => MyFutureBuilder<Family>(
         future: _future,
-        builder: (context, family) => Scaffold(
+        builder: (BuildContext context, Family family) => Scaffold(
           appBar: AppBar(title: Text(family.name)),
           body: ListView(
-            children: [
-              for (final p in family.people)
+            children: <Widget>[
+              for (final Person p in family.people)
                 ListTile(
                   title: Text(p.name),
                   onTap: () => context.go(
@@ -284,11 +320,16 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatefulWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.fid, required this.pid, Key? key})
       : super(key: key);
 
+  /// The id of family the person belongs to.
   final String fid;
+
+  /// The person id.
   final String pid;
 
   @override
@@ -309,7 +350,9 @@
     super.didUpdateWidget(oldWidget);
 
     // refresh cached data
-    if (oldWidget.fid != widget.fid || oldWidget.pid != widget.pid) _fetch();
+    if (oldWidget.fid != widget.fid || oldWidget.pid != widget.pid) {
+      _fetch();
+    }
   }
 
   void _fetch() => _future = _repo.getPerson(widget.fid, widget.pid);
@@ -318,7 +361,7 @@
   @override
   Widget build(BuildContext context) => MyFutureBuilder<FamilyPerson>(
         future: _future,
-        builder: (context, famper) => Scaffold(
+        builder: (BuildContext context, FamilyPerson famper) => Scaffold(
           appBar: AppBar(title: Text(famper.person.name)),
           body: Text(
             '${famper.person.name} ${famper.family.name} is '
@@ -328,17 +371,22 @@
       );
 }
 
+/// A custom [Future] builder.
 class MyFutureBuilder<T extends Object> extends StatelessWidget {
+  /// Creates a [MyFutureBuilder].
   const MyFutureBuilder({required this.future, required this.builder, Key? key})
       : super(key: key);
 
+  /// The [Future] to depend on.
   final Future<T>? future;
+
+  /// The builder that builds the widget subtree.
   final Widget Function(BuildContext context, T data) builder;
 
   @override
   Widget build(BuildContext context) => FutureBuilder<T>(
         future: future,
-        builder: (context, snapshot) {
+        builder: (BuildContext context, AsyncSnapshot<T> snapshot) {
           if (snapshot.connectionState == ConnectionState.waiting) {
             return Scaffold(
               appBar: AppBar(title: const Text('Loading...')),
@@ -359,17 +407,21 @@
       );
 }
 
+/// The error widget.
 class SnapshotError extends StatelessWidget {
+  /// Creates a [SnapshotError].
   SnapshotError(Object error, {Key? key})
       : error = error is Exception ? error : Exception(error),
         super(key: key);
+
+  /// The error to display.
   final Exception error;
 
   @override
   Widget build(BuildContext context) => Center(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
-          children: [
+          children: <Widget>[
             SelectableText(error.toString()),
             TextButton(
               onPressed: () => context.go('/'),
diff --git a/packages/go_router/example/lib/main.dart b/packages/go_router/example/lib/main.dart
index bf2c5d4..ef33494 100644
--- a/packages/go_router/example/lib/main.dart
+++ b/packages/go_router/example/lib/main.dart
@@ -7,10 +7,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Declarative Routes';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Declarative Routes';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -19,21 +22,25 @@
         title: title,
       );
 
-  final _router = GoRouter(
-    routes: [
+  final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page2Screen(),
       ),
     ],
   );
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -42,7 +49,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/page2'),
                 child: const Text('Go to page 2'),
@@ -53,7 +60,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -62,7 +71,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/'),
                 child: const Text('Go to home page'),
diff --git a/packages/go_router/example/lib/named_routes.dart b/packages/go_router/example/lib/named_routes.dart
index 34bc16a..648610d 100644
--- a/packages/go_router/example/lib/named_routes.dart
+++ b/packages/go_router/example/lib/named_routes.dart
@@ -10,15 +10,19 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  final loginInfo = LoginInfo();
-  static const title = 'GoRouter Example: Named Routes';
+  final LoginInfo _loginInfo = LoginInfo();
+
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Named Routes';
 
   @override
   Widget build(BuildContext context) => ChangeNotifierProvider<LoginInfo>.value(
-        value: loginInfo,
+        value: _loginInfo,
         child: MaterialApp.router(
           routeInformationParser: _router.routeInformationParser,
           routerDelegate: _router.routerDelegate,
@@ -27,27 +31,29 @@
         ),
       );
 
-  late final _router = GoRouter(
+  late final GoRouter _router = GoRouter(
     debugLogDiagnostics: true,
-    routes: [
+    routes: <GoRoute>[
       GoRoute(
         name: 'home',
         path: '/',
-        builder: (context, state) => HomeScreen(families: Families.data),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            HomeScreen(families: Families.data),
+        routes: <GoRoute>[
           GoRoute(
             name: 'family',
             path: 'family/:fid',
-            builder: (context, state) => FamilyScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreen(
               family: Families.family(state.params['fid']!),
             ),
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 name: 'person',
                 path: 'person/:pid',
-                builder: (context, state) {
-                  final family = Families.family(state.params['fid']!);
-                  final person = family.person(state.params['pid']!);
+                builder: (BuildContext context, GoRouterState state) {
+                  final Family family = Families.family(state.params['fid']!);
+                  final Person person = family.person(state.params['pid']!);
                   return PersonScreen(family: family, person: person);
                 },
               ),
@@ -58,54 +64,63 @@
       GoRoute(
         name: 'login',
         path: '/login',
-        builder: (context, state) => const LoginScreen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const LoginScreen(),
       ),
     ],
 
     // redirect to the login page if the user is not logged in
-    redirect: (state) {
+    redirect: (GoRouterState state) {
       // if the user is not logged in, they need to login
-      final loggedIn = loginInfo.loggedIn;
-      final loginloc = state.namedLocation('login');
-      final loggingIn = state.subloc == loginloc;
+      final bool loggedIn = _loginInfo.loggedIn;
+      final String loginloc = state.namedLocation('login');
+      final bool loggingIn = state.subloc == loginloc;
 
       // bundle the location the user is coming from into a query parameter
-      final homeloc = state.namedLocation('home');
-      final fromloc = state.subloc == homeloc ? '' : state.subloc;
+      final String homeloc = state.namedLocation('home');
+      final String fromloc = state.subloc == homeloc ? '' : state.subloc;
       if (!loggedIn) {
         return loggingIn
             ? null
             : state.namedLocation(
                 'login',
-                queryParams: {if (fromloc.isNotEmpty) 'from': fromloc},
+                queryParams: <String, String>{
+                  if (fromloc.isNotEmpty) 'from': fromloc
+                },
               );
       }
 
       // if the user is logged in, send them where they were going before (or
       // home if they weren't going anywhere)
-      if (loggingIn) return state.queryParams['from'] ?? homeloc;
+      if (loggingIn) {
+        return state.queryParams['from'] ?? homeloc;
+      }
 
       // no need to redirect at all
       return null;
     },
 
     // changes on the listenable will cause the router to refresh it's route
-    refreshListenable: loginInfo,
+    refreshListenable: _loginInfo,
   );
 }
 
+/// The home screen that shows a list of families.
 class HomeScreen extends StatelessWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({required this.families, Key? key}) : super(key: key);
+
+  /// The list of families.
   final List<Family> families;
 
   @override
   Widget build(BuildContext context) {
-    final info = context.read<LoginInfo>();
+    final LoginInfo info = context.read<LoginInfo>();
 
     return Scaffold(
       appBar: AppBar(
         title: const Text(App.title),
-        actions: [
+        actions: <Widget>[
           IconButton(
             onPressed: info.logout,
             tooltip: 'Logout: ${info.userName}',
@@ -114,11 +129,12 @@
         ],
       ),
       body: ListView(
-        children: [
-          for (final f in families)
+        children: <Widget>[
+          for (final Family f in families)
             ListTile(
               title: Text(f.name),
-              onTap: () => context.goNamed('family', params: {'fid': f.id}),
+              onTap: () => context
+                  .goNamed('family', params: <String, String>{'fid': f.id}),
             )
         ],
       ),
@@ -126,22 +142,26 @@
   }
 }
 
+/// The screen that shows a list of persons in a family.
 class FamilyScreen extends StatelessWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: Text(family.name)),
         body: ListView(
-          children: [
-            for (final p in family.people)
+          children: <Widget>[
+            for (final Person p in family.people)
               ListTile(
                 title: Text(p.name),
                 onTap: () => context.go(context.namedLocation(
                   'person',
-                  params: {'fid': family.id, 'pid': p.id},
-                  queryParams: {'qid': 'quid'},
+                  params: <String, String>{'fid': family.id, 'pid': p.id},
+                  queryParams: <String, String>{'qid': 'quid'},
                 )),
               ),
           ],
@@ -149,11 +169,16 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.family, required this.person, Key? key})
       : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
@@ -163,7 +188,9 @@
       );
 }
 
+/// The login screen.
 class LoginScreen extends StatelessWidget {
+  /// Creates a [LoginScreen].
   const LoginScreen({Key? key}) : super(key: key);
 
   @override
@@ -172,7 +199,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () {
                   // log a user in, letting all the listeners know
diff --git a/packages/go_router/example/lib/nav_builder.dart b/packages/go_router/example/lib/nav_builder.dart
index 2d532b3..ba8818f 100644
--- a/packages/go_router/example/lib/nav_builder.dart
+++ b/packages/go_router/example/lib/nav_builder.dart
@@ -10,11 +10,15 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  final loginInfo = LoginInfo();
-  static const title = 'GoRouter Example: Navigator Builder';
+  final LoginInfo _loginInfo = LoginInfo();
+
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Navigator Builder';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -23,29 +27,29 @@
         title: title,
       );
 
-  late final _router = GoRouter(
+  late final GoRouter _router = GoRouter(
     debugLogDiagnostics: true,
-    routes: [
+    routes: <GoRoute>[
       GoRoute(
         name: 'home',
         path: '/',
-        builder: (context, state) =>
+        builder: (BuildContext context, GoRouterState state) =>
             HomeScreenNoLogout(families: Families.data),
-        routes: [
+        routes: <GoRoute>[
           GoRoute(
             name: 'family',
             path: 'family/:fid',
-            builder: (context, state) {
-              final family = Families.family(state.params['fid']!);
+            builder: (BuildContext context, GoRouterState state) {
+              final Family family = Families.family(state.params['fid']!);
               return FamilyScreen(family: family);
             },
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 name: 'person',
                 path: 'person/:pid',
-                builder: (context, state) {
-                  final family = Families.family(state.params['fid']!);
-                  final person = family.person(state.params['pid']!);
+                builder: (BuildContext context, GoRouterState state) {
+                  final Family family = Families.family(state.params['fid']!);
+                  final Person person = family.person(state.params['pid']!);
                   return PersonScreen(family: family, person: person);
                 },
               ),
@@ -56,63 +60,71 @@
       GoRoute(
         name: 'login',
         path: '/login',
-        builder: (context, state) => const LoginScreen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const LoginScreen(),
       ),
     ],
 
     // redirect to the login page if the user is not logged in
-    redirect: (state) {
+    redirect: (GoRouterState state) {
       // if the user is not logged in, they need to login
-      final loggedIn = loginInfo.loggedIn;
-      final loginloc = state.namedLocation('login');
-      final loggingIn = state.subloc == loginloc;
+      final bool loggedIn = _loginInfo.loggedIn;
+      final String loginloc = state.namedLocation('login');
+      final bool loggingIn = state.subloc == loginloc;
 
       // bundle the location the user is coming from into a query parameter
-      final homeloc = state.namedLocation('home');
-      final fromloc = state.subloc == homeloc ? '' : state.subloc;
+      final String homeloc = state.namedLocation('home');
+      final String fromloc = state.subloc == homeloc ? '' : state.subloc;
       if (!loggedIn) {
         return loggingIn
             ? null
             : state.namedLocation(
                 'login',
-                queryParams: {if (fromloc.isNotEmpty) 'from': fromloc},
+                queryParams: <String, String>{
+                  if (fromloc.isNotEmpty) 'from': fromloc
+                },
               );
       }
 
       // if the user is logged in, send them where they were going before (or
       // home if they weren't going anywhere)
-      if (loggingIn) return state.queryParams['from'] ?? homeloc;
+      if (loggingIn) {
+        return state.queryParams['from'] ?? homeloc;
+      }
 
       // no need to redirect at all
       return null;
     },
 
     // changes on the listenable will cause the router to refresh it's route
-    refreshListenable: loginInfo,
+    refreshListenable: _loginInfo,
 
     // add a wrapper around the navigator to:
     // - put loginInfo into the widget tree, and to
     // - add an overlay to show a logout option
-    navigatorBuilder: (context, state, child) =>
-        ChangeNotifierProvider<LoginInfo>.value(
-      value: loginInfo,
-      builder: (context, _) {
+    navigatorBuilder:
+        (BuildContext context, GoRouterState state, Widget child) =>
+            ChangeNotifierProvider<LoginInfo>.value(
+      value: _loginInfo,
+      builder: (BuildContext context, Widget? _) {
         debugPrint('navigatorBuilder: ${state.subloc}');
-        return loginInfo.loggedIn ? AuthOverlay(child: child) : child;
+        return _loginInfo.loggedIn ? AuthOverlay(child: child) : child;
       },
     ),
   );
 }
 
-// A simple class for placing an exit button on top of all screens
+/// A simple class for placing an exit button on top of all screens.
 class AuthOverlay extends StatelessWidget {
+  /// Creates an [AuthOverlay].
   const AuthOverlay({required this.child, Key? key}) : super(key: key);
 
+  /// The child subtree.
   final Widget child;
 
   @override
   Widget build(BuildContext context) => Stack(
-        children: [
+        children: <Widget>[
           child,
           Positioned(
             top: 90,
@@ -129,36 +141,45 @@
       );
 }
 
+/// The home screen without a logout button.
 class HomeScreenNoLogout extends StatelessWidget {
+  /// Creates a [HomeScreenNoLogout].
   const HomeScreenNoLogout({required this.families, Key? key})
       : super(key: key);
+
+  /// The list of families.
   final List<Family> families;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: const Text(App.title)),
         body: ListView(
-          children: [
-            for (final f in families)
+          children: <Widget>[
+            for (final Family f in families)
               ListTile(
                 title: Text(f.name),
-                onTap: () => context.goNamed('family', params: {'fid': f.id}),
+                onTap: () => context
+                    .goNamed('family', params: <String, String>{'fid': f.id}),
               )
           ],
         ),
       );
 }
 
+/// The screen that shows a list of persons in a family.
 class FamilyScreen extends StatelessWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: Text(family.name)),
         body: ListView(
-          children: [
-            for (final p in family.people)
+          children: <Widget>[
+            for (final Person p in family.people)
               ListTile(
                 title: Text(p.name),
                 onTap: () => context.go('/family/${family.id}/person/${p.id}'),
@@ -168,11 +189,16 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.family, required this.person, Key? key})
       : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
@@ -182,7 +208,9 @@
       );
 }
 
+/// The login screen.
 class LoginScreen extends StatelessWidget {
+  /// Creates a [LoginScreen].
   const LoginScreen({Key? key}) : super(key: key);
 
   @override
@@ -191,7 +219,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () {
                   // log a user in, letting all the listeners know
diff --git a/packages/go_router/example/lib/nav_observer.dart b/packages/go_router/example/lib/nav_observer.dart
index c3dc7a7..51cf45a 100644
--- a/packages/go_router/example/lib/nav_observer.dart
+++ b/packages/go_router/example/lib/nav_observer.dart
@@ -8,10 +8,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Navigator Observer';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Navigator Observer';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -20,23 +23,26 @@
         title: title,
       );
 
-  final _router = GoRouter(
-    observers: [MyNavObserver()],
-    routes: [
+  final GoRouter _router = GoRouter(
+    observers: <NavigatorObserver>[MyNavObserver()],
+    routes: <GoRoute>[
       GoRoute(
         // if there's no name, path will be used as name for observers
         path: '/',
-        builder: (context, state) => const Page1Screen(),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
+        routes: <GoRoute>[
           GoRoute(
             name: 'page2',
             path: 'page2/:p1',
-            builder: (context, state) => const Page2Screen(),
-            routes: [
+            builder: (BuildContext context, GoRouterState state) =>
+                const Page2Screen(),
+            routes: <GoRoute>[
               GoRoute(
                 name: 'page3',
                 path: 'page3',
-                builder: (context, state) => const Page3Screen(),
+                builder: (BuildContext context, GoRouterState state) =>
+                    const Page3Screen(),
               ),
             ],
           ),
@@ -46,12 +52,15 @@
   );
 }
 
+/// The Navigator observer.
 class MyNavObserver extends NavigatorObserver {
+  /// Creates a [MyNavObserver].
   MyNavObserver() {
-    log.onRecord.listen((e) => debugPrint('$e'));
+    log.onRecord.listen((LogRecord e) => debugPrint('$e'));
   }
 
-  final log = Logger('MyNavObserver');
+  /// The logged message.
+  final Logger log = Logger('MyNavObserver');
 
   @override
   void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) =>
@@ -85,7 +94,9 @@
   String get str => 'route(${settings.name}: ${settings.arguments})';
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -94,12 +105,12 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.goNamed(
                   'page2',
-                  params: {'p1': 'pv1'},
-                  queryParams: {'q1': 'qv1'},
+                  params: <String, String>{'p1': 'pv1'},
+                  queryParams: <String, String>{'q1': 'qv1'},
                 ),
                 child: const Text('Go to page 2'),
               ),
@@ -109,7 +120,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -118,11 +131,11 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.goNamed(
                   'page3',
-                  params: {'p1': 'pv2'},
+                  params: <String, String>{'p1': 'pv2'},
                 ),
                 child: const Text('Go to page 3'),
               ),
@@ -132,7 +145,9 @@
       );
 }
 
+/// The screen of the third page.
 class Page3Screen extends StatelessWidget {
+  /// Creates a [Page3Screen].
   const Page3Screen({Key? key}) : super(key: key);
 
   @override
@@ -141,7 +156,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/'),
                 child: const Text('Go to home page'),
diff --git a/packages/go_router/example/lib/nested_nav.dart b/packages/go_router/example/lib/nested_nav.dart
index 45846b0..5940f73 100644
--- a/packages/go_router/example/lib/nested_nav.dart
+++ b/packages/go_router/example/lib/nested_nav.dart
@@ -9,10 +9,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Nested Navigation';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Nested Navigation';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -21,24 +24,25 @@
         title: title,
       );
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
         redirect: (_) => '/family/${Families.data[0].id}',
       ),
       GoRoute(
         path: '/family/:fid',
-        builder: (context, state) => FamilyTabsScreen(
+        builder: (BuildContext context, GoRouterState state) =>
+            FamilyTabsScreen(
           key: state.pageKey,
           selectedFamily: Families.family(state.params['fid']!),
         ),
-        routes: [
+        routes: <GoRoute>[
           GoRoute(
             path: 'person/:pid',
-            builder: (context, state) {
-              final family = Families.family(state.params['fid']!);
-              final person = family.person(state.params['pid']!);
+            builder: (BuildContext context, GoRouterState state) {
+              final Family family = Families.family(state.params['fid']!);
+              final Person person = family.person(state.params['pid']!);
 
               return PersonScreen(family: family, person: person);
             },
@@ -50,9 +54,10 @@
     // show the current router location as the user navigates page to page; note
     // that this is not required for nested navigation but it is useful to show
     // the location as it changes
-    navigatorBuilder: (context, state, child) => Material(
+    navigatorBuilder:
+        (BuildContext context, GoRouterState state, Widget child) => Material(
       child: Column(
-        children: [
+        children: <Widget>[
           Expanded(child: child),
           Padding(
             padding: const EdgeInsets.all(8),
@@ -64,13 +69,17 @@
   );
 }
 
+/// The family tabs screen.
 class FamilyTabsScreen extends StatefulWidget {
+  /// Creates a [FamilyTabsScreen].
   FamilyTabsScreen({required Family selectedFamily, Key? key})
-      : index = Families.data.indexWhere((f) => f.id == selectedFamily.id),
+      : index =
+            Families.data.indexWhere((Family f) => f.id == selectedFamily.id),
         super(key: key) {
     assert(index != -1);
   }
 
+  /// The tab index.
   final int index;
 
   @override
@@ -109,13 +118,17 @@
           title: const Text(App.title),
           bottom: TabBar(
             controller: _controller,
-            tabs: [for (final f in Families.data) Tab(text: f.name)],
-            onTap: (index) => _tap(context, index),
+            tabs: <Tab>[
+              for (final Family f in Families.data) Tab(text: f.name)
+            ],
+            onTap: (int index) => _tap(context, index),
           ),
         ),
         body: TabBarView(
           controller: _controller,
-          children: [for (final f in Families.data) FamilyView(family: f)],
+          children: <Widget>[
+            for (final Family f in Families.data) FamilyView(family: f)
+          ],
         ),
       );
 
@@ -123,8 +136,12 @@
       context.go('/family/${Families.data[index].id}');
 }
 
+/// The family view.
 class FamilyView extends StatefulWidget {
+  /// Creates a [FamilyView].
   const FamilyView({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
@@ -151,8 +168,8 @@
     // Call `super.build` when using `AutomaticKeepAliveClientMixin`.
     super.build(context);
     return ListView(
-      children: [
-        for (final p in widget.family.people)
+      children: <Widget>[
+        for (final Person p in widget.family.people)
           ListTile(
             title: Text(p.name),
             onTap: () =>
@@ -163,11 +180,16 @@
   }
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.family, required this.person, Key? key})
       : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
diff --git a/packages/go_router/example/lib/push.dart b/packages/go_router/example/lib/push.dart
index 97cd03c..9d24495 100644
--- a/packages/go_router/example/lib/push.dart
+++ b/packages/go_router/example/lib/push.dart
@@ -7,10 +7,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Push';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Push';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -19,15 +22,17 @@
         title: title,
       );
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1ScreenWithPush(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1ScreenWithPush(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => Page2ScreenWithPush(
+        builder: (BuildContext context, GoRouterState state) =>
+            Page2ScreenWithPush(
           int.parse(state.queryParams['push-count']!),
         ),
       ),
@@ -35,7 +40,9 @@
   );
 }
 
+/// The screen of the first page.
 class Page1ScreenWithPush extends StatelessWidget {
+  /// Creates a [Page1ScreenWithPush].
   const Page1ScreenWithPush({Key? key}) : super(key: key);
 
   @override
@@ -44,7 +51,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.push('/page2?push-count=1'),
                 child: const Text('Push page 2'),
@@ -55,8 +62,12 @@
       );
 }
 
+/// The screen of the second page.
 class Page2ScreenWithPush extends StatelessWidget {
+  /// Creates a [Page2ScreenWithPush].
   const Page2ScreenWithPush(this.pushCount, {Key? key}) : super(key: key);
+
+  /// The push count.
   final int pushCount;
 
   @override
@@ -67,7 +78,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               Padding(
                 padding: const EdgeInsets.all(8),
                 child: ElevatedButton(
diff --git a/packages/go_router/example/lib/query_params.dart b/packages/go_router/example/lib/query_params.dart
index f3fc748..9a660ae 100644
--- a/packages/go_router/example/lib/query_params.dart
+++ b/packages/go_router/example/lib/query_params.dart
@@ -10,16 +10,20 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  final loginInfo = LoginInfo();
-  static const title = 'GoRouter Example: Query Parameters';
+  final LoginInfo _loginInfo = LoginInfo();
+
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Query Parameters';
 
   // add the login info into the tree as app state that can change over time
   @override
   Widget build(BuildContext context) => ChangeNotifierProvider<LoginInfo>.value(
-        value: loginInfo,
+        value: _loginInfo,
         child: MaterialApp.router(
           routeInformationParser: _router.routeInformationParser,
           routerDelegate: _router.routerDelegate,
@@ -28,23 +32,25 @@
         ),
       );
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => HomeScreen(families: Families.data),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            HomeScreen(families: Families.data),
+        routes: <GoRoute>[
           GoRoute(
             path: 'family/:fid',
-            builder: (context, state) => FamilyScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreen(
               family: Families.family(state.params['fid']!),
             ),
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 path: 'person/:pid',
-                builder: (context, state) {
-                  final family = Families.family(state.params['fid']!);
-                  final person = family.person(state.params['pid']!);
+                builder: (BuildContext context, GoRouterState state) {
+                  final Family family = Families.family(state.params['fid']!);
+                  final Person person = family.person(state.params['pid']!);
                   return PersonScreen(family: family, person: person);
                 },
               ),
@@ -54,45 +60,54 @@
       ),
       GoRoute(
         path: '/login',
-        builder: (context, state) => const LoginScreen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const LoginScreen(),
       ),
     ],
 
     // redirect to the login page if the user is not logged in
-    redirect: (state) {
+    redirect: (GoRouterState state) {
       // if the user is not logged in, they need to login
-      final loggedIn = loginInfo.loggedIn;
-      final loggingIn = state.subloc == '/login';
+      final bool loggedIn = _loginInfo.loggedIn;
+      final bool loggingIn = state.subloc == '/login';
 
       // bundle the location the user is coming from into a query parameter
-      final fromp = state.subloc == '/' ? '' : '?from=${state.subloc}';
-      if (!loggedIn) return loggingIn ? null : '/login$fromp';
+      final String fromp = state.subloc == '/' ? '' : '?from=${state.subloc}';
+      if (!loggedIn) {
+        return loggingIn ? null : '/login$fromp';
+      }
 
       // if the user is logged in, send them where they were going before (or
       // home if they weren't going anywhere)
-      if (loggingIn) return state.queryParams['from'] ?? '/';
+      if (loggingIn) {
+        return state.queryParams['from'] ?? '/';
+      }
 
       // no need to redirect at all
       return null;
     },
 
     // changes on the listenable will cause the router to refresh it's route
-    refreshListenable: loginInfo,
+    refreshListenable: _loginInfo,
   );
 }
 
+/// The home screen that shows a list of families.
 class HomeScreen extends StatelessWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({required this.families, Key? key}) : super(key: key);
+
+  /// The list of families.
   final List<Family> families;
 
   @override
   Widget build(BuildContext context) {
-    final info = context.read<LoginInfo>();
+    final LoginInfo info = context.read<LoginInfo>();
 
     return Scaffold(
       appBar: AppBar(
         title: const Text(App.title),
-        actions: [
+        actions: <Widget>[
           IconButton(
             onPressed: () {
               info.logout();
@@ -104,8 +119,8 @@
         ],
       ),
       body: ListView(
-        children: [
-          for (final f in families)
+        children: <Widget>[
+          for (final Family f in families)
             ListTile(
               title: Text(f.name),
               onTap: () => context.go('/family/${f.id}'),
@@ -116,16 +131,20 @@
   }
 }
 
+/// The screen that shows a list of persons in a family.
 class FamilyScreen extends StatelessWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: Text(family.name)),
         body: ListView(
-          children: [
-            for (final p in family.people)
+          children: <Widget>[
+            for (final Person p in family.people)
               ListTile(
                 title: Text(p.name),
                 onTap: () => context.go('/family/${family.id}/person/${p.id}'),
@@ -135,11 +154,16 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.family, required this.person, Key? key})
       : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
@@ -149,7 +173,9 @@
       );
 }
 
+/// The login screen.
 class LoginScreen extends StatelessWidget {
+  /// Creates a [LoginScreen].
   const LoginScreen({Key? key}) : super(key: key);
 
   @override
@@ -158,7 +184,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () {
                   // log a user in, letting all the listeners know
diff --git a/packages/go_router/example/lib/redirection.dart b/packages/go_router/example/lib/redirection.dart
index c358554..395e727 100644
--- a/packages/go_router/example/lib/redirection.dart
+++ b/packages/go_router/example/lib/redirection.dart
@@ -10,16 +10,20 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  final loginInfo = LoginInfo();
-  static const title = 'GoRouter Example: Redirection';
+  final LoginInfo _loginInfo = LoginInfo();
+
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Redirection';
 
   // add the login info into the tree as app state that can change over time
   @override
   Widget build(BuildContext context) => ChangeNotifierProvider<LoginInfo>.value(
-        value: loginInfo,
+        value: _loginInfo,
         child: MaterialApp.router(
           routeInformationParser: _router.routeInformationParser,
           routerDelegate: _router.routerDelegate,
@@ -28,23 +32,25 @@
         ),
       );
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => HomeScreen(families: Families.data),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            HomeScreen(families: Families.data),
+        routes: <GoRoute>[
           GoRoute(
             path: 'family/:fid',
-            builder: (context, state) => FamilyScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreen(
               family: Families.family(state.params['fid']!),
             ),
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 path: 'person/:pid',
-                builder: (context, state) {
-                  final family = Families.family(state.params['fid']!);
-                  final person = family.person(state.params['pid']!);
+                builder: (BuildContext context, GoRouterState state) {
+                  final Family family = Families.family(state.params['fid']!);
+                  final Person person = family.person(state.params['pid']!);
                   return PersonScreen(family: family, person: person);
                 },
               ),
@@ -54,31 +60,38 @@
       ),
       GoRoute(
         path: '/login',
-        builder: (context, state) => const LoginScreen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const LoginScreen(),
       ),
     ],
 
     // redirect to the login page if the user is not logged in
-    redirect: (state) {
+    redirect: (GoRouterState state) {
       // if the user is not logged in, they need to login
-      final loggedIn = loginInfo.loggedIn;
-      final loggingIn = state.subloc == '/login';
-      if (!loggedIn) return loggingIn ? null : '/login';
+      final bool loggedIn = _loginInfo.loggedIn;
+      final bool loggingIn = state.subloc == '/login';
+      if (!loggedIn) {
+        return loggingIn ? null : '/login';
+      }
 
       // if the user is logged in but still on the login page, send them to
       // the home page
-      if (loggingIn) return '/';
+      if (loggingIn) {
+        return '/';
+      }
 
       // no need to redirect at all
       return null;
     },
 
     // changes on the listenable will cause the router to refresh it's route
-    refreshListenable: loginInfo,
+    refreshListenable: _loginInfo,
   );
 }
 
+/// The login screen.
 class LoginScreen extends StatelessWidget {
+  /// Creates a [LoginScreen].
   const LoginScreen({Key? key}) : super(key: key);
 
   @override
@@ -87,7 +100,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () {
                   // log a user in, letting all the listeners know
@@ -105,18 +118,22 @@
       );
 }
 
+/// The home screen that shows a list of families.
 class HomeScreen extends StatelessWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({required this.families, Key? key}) : super(key: key);
+
+  /// The list of families.
   final List<Family> families;
 
   @override
   Widget build(BuildContext context) {
-    final info = context.read<LoginInfo>();
+    final LoginInfo info = context.read<LoginInfo>();
 
     return Scaffold(
       appBar: AppBar(
         title: const Text(App.title),
-        actions: [
+        actions: <Widget>[
           IconButton(
             onPressed: info.logout,
             tooltip: 'Logout: ${info.userName}',
@@ -125,8 +142,8 @@
         ],
       ),
       body: ListView(
-        children: [
-          for (final f in families)
+        children: <Widget>[
+          for (final Family f in families)
             ListTile(
               title: Text(f.name),
               onTap: () => context.go('/family/${f.id}'),
@@ -137,16 +154,20 @@
   }
 }
 
+/// The screen that shows a list of persons in a family.
 class FamilyScreen extends StatelessWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: Text(family.name)),
         body: ListView(
-          children: [
-            for (final p in family.people)
+          children: <Widget>[
+            for (final Person p in family.people)
               ListTile(
                 title: Text(p.name),
                 onTap: () => context.go('/family/${family.id}/person/${p.id}'),
@@ -156,11 +177,16 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.family, required this.person, Key? key})
       : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
diff --git a/packages/go_router/example/lib/router_neglect.dart b/packages/go_router/example/lib/router_neglect.dart
index 119d922..0e3ebac 100644
--- a/packages/go_router/example/lib/router_neglect.dart
+++ b/packages/go_router/example/lib/router_neglect.dart
@@ -7,10 +7,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Router neglect';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Router neglect';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -19,23 +22,27 @@
         title: title,
       );
 
-  final _router = GoRouter(
+  final GoRouter _router = GoRouter(
     // turn off history tracking in the browser for this navigation
     routerNeglect: true,
-    routes: [
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page2Screen(),
       ),
     ],
   );
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -44,7 +51,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/page2'),
                 child: const Text('Go to page 2'),
@@ -66,7 +73,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -75,7 +84,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/'),
                 child: const Text('Go to home page'),
diff --git a/packages/go_router/example/lib/router_stream_refresh.dart b/packages/go_router/example/lib/router_stream_refresh.dart
index 8271a36..cb4607e 100644
--- a/packages/go_router/example/lib/router_stream_refresh.dart
+++ b/packages/go_router/example/lib/router_stream_refresh.dart
@@ -10,10 +10,13 @@
 
 void main() => runApp(const App());
 
+/// The main app.
 class App extends StatefulWidget {
+  /// Creates an [App].
   const App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Stream Refresh';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Stream Refresh';
 
   @override
   State<App> createState() => _AppState();
@@ -27,22 +30,24 @@
   void initState() {
     loggedInState = LoggedInState.seeded(false);
     router = GoRouter(
-      routes: [
+      routes: <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (context, state) => HomeScreen(families: Families.data),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              HomeScreen(families: Families.data),
+          routes: <GoRoute>[
             GoRoute(
               path: 'family/:fid',
-              builder: (context, state) => FamilyScreen(
+              builder: (BuildContext context, GoRouterState state) =>
+                  FamilyScreen(
                 family: Families.family(state.params['fid']!),
               ),
-              routes: [
+              routes: <GoRoute>[
                 GoRoute(
                   path: 'person/:pid',
-                  builder: (context, state) {
-                    final family = Families.family(state.params['fid']!);
-                    final person = family.person(state.params['pid']!);
+                  builder: (BuildContext context, GoRouterState state) {
+                    final Family family = Families.family(state.params['fid']!);
+                    final Person person = family.person(state.params['pid']!);
                     return PersonScreen(family: family, person: person);
                   },
                 ),
@@ -52,23 +57,28 @@
         ),
         GoRoute(
           path: '/login',
-          builder: (context, state) => const LoginScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const LoginScreen(),
         ),
       ],
 
       // redirect to the login page if the user is not logged in
-      redirect: (state) {
+      redirect: (GoRouterState state) {
         // if the user is not logged in, they need to login
-        final loggedIn = loggedInState.state;
-        final loggingIn = state.subloc == '/login';
+        final bool loggedIn = loggedInState.state;
+        final bool loggingIn = state.subloc == '/login';
 
         // bundle the location the user is coming from into a query parameter
-        final fromp = state.subloc == '/' ? '' : '?from=${state.subloc}';
-        if (!loggedIn) return loggingIn ? null : '/login$fromp';
+        final String fromp = state.subloc == '/' ? '' : '?from=${state.subloc}';
+        if (!loggedIn) {
+          return loggingIn ? null : '/login$fromp';
+        }
 
         // if the user is logged in, send them where they were going before (or
         // home if they weren't going anywhere)
-        if (loggingIn) return state.queryParams['from'] ?? '/';
+        if (loggingIn) {
+          return state.queryParams['from'] ?? '/';
+        }
 
         // no need to redirect at all
         return null;
@@ -98,22 +108,25 @@
   }
 }
 
+/// The home screen that shows a list of families.
 class HomeScreen extends StatelessWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({
     required this.families,
     Key? key,
   }) : super(key: key);
 
+  /// The list of families.
   final List<Family> families;
 
   @override
   Widget build(BuildContext context) {
-    final info = context.read<LoggedInState>();
+    final LoggedInState info = context.read<LoggedInState>();
 
     return Scaffold(
       appBar: AppBar(
         title: const Text(App.title),
-        actions: [
+        actions: <Widget>[
           IconButton(
             onPressed: () => info.emit(false),
             icon: const Icon(Icons.logout),
@@ -121,8 +134,8 @@
         ],
       ),
       body: ListView(
-        children: [
-          for (final f in families)
+        children: <Widget>[
+          for (final Family f in families)
             ListTile(
               title: Text(f.name),
               onTap: () => context.go('/family/${f.id}'),
@@ -133,19 +146,23 @@
   }
 }
 
+/// The screen that shows a list of persons in a family.
 class FamilyScreen extends StatelessWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({
     required this.family,
     Key? key,
   }) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: Text(family.name)),
         body: ListView(
-          children: [
-            for (final p in family.people)
+          children: <Widget>[
+            for (final Person p in family.people)
               ListTile(
                 title: Text(p.name),
                 onTap: () => context.go('/family/${family.id}/person/${p.id}'),
@@ -155,14 +172,19 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({
     required this.family,
     required this.person,
     Key? key,
   }) : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
@@ -172,7 +194,9 @@
       );
 }
 
+/// The login screen.
 class LoginScreen extends StatelessWidget {
+  /// Creates a [LoginScreen].
   const LoginScreen({Key? key}) : super(key: key);
 
   @override
@@ -181,7 +205,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () {
                   // log a user in, letting all the listeners know
diff --git a/packages/go_router/example/lib/shared/data.dart b/packages/go_router/example/lib/shared/data.dart
index db7dff4..a9a84b7 100644
--- a/packages/go_router/example/lib/shared/data.dart
+++ b/packages/go_router/example/lib/shared/data.dart
@@ -7,33 +7,52 @@
 
 import 'package:flutter/foundation.dart';
 
+/// Person data class.
 class Person {
+  /// Creates a [Person].
   Person({required this.id, required this.name, required this.age});
 
+  /// The id of the person.
   final String id;
+
+  /// The name of the person.
   final String name;
+
+  /// The age of the person.
   final int age;
 }
 
+/// Family data class.
 class Family {
+  /// Creates a [Family].
   Family({required this.id, required this.name, required this.people});
 
+  /// The id of the family.
   final String id;
+
+  /// The name of the family.
   final String name;
+
+  /// The list of [Person]s in the family.
   final List<Person> people;
 
+  /// Gets the [Person] with the given id in this family.
   Person person(String pid) => people.singleWhere(
-        (p) => p.id == pid,
+        (Person p) => p.id == pid,
         orElse: () => throw Exception('unknown person $pid for family $id'),
       );
 }
 
+/// The mock of families data.
 class Families {
-  static final data = [
+  Families._();
+
+  /// The data.
+  static final List<Family> data = <Family>[
     Family(
       id: 'f1',
       name: 'Sells',
-      people: [
+      people: <Person>[
         Person(id: 'p1', name: 'Chris', age: 52),
         Person(id: 'p2', name: 'John', age: 27),
         Person(id: 'p3', name: 'Tom', age: 26),
@@ -42,7 +61,7 @@
     Family(
       id: 'f2',
       name: 'Addams',
-      people: [
+      people: <Person>[
         Person(id: 'p1', name: 'Gomez', age: 55),
         Person(id: 'p2', name: 'Morticia', age: 50),
         Person(id: 'p3', name: 'Pugsley', age: 10),
@@ -52,7 +71,7 @@
     Family(
       id: 'f3',
       name: 'Hunting',
-      people: [
+      people: <Person>[
         Person(id: 'p1', name: 'Mom', age: 54),
         Person(id: 'p2', name: 'Dad', age: 55),
         Person(id: 'p3', name: 'Will', age: 20),
@@ -72,43 +91,56 @@
     ),
   ];
 
+  /// Looks up a family in the data.
   static Family family(String fid) => data.family(fid);
 }
 
 extension on List<Family> {
   Family family(String fid) => singleWhere(
-        (f) => f.id == fid,
+        (Family f) => f.id == fid,
         orElse: () => throw Exception('unknown family $fid'),
       );
 }
 
+/// The login information.
 class LoginInfo extends ChangeNotifier {
-  var _userName = '';
+  /// The username of login.
   String get userName => _userName;
+  String _userName = '';
+
+  /// Whether a user has logged in.
   bool get loggedIn => _userName.isNotEmpty;
 
+  /// Logs in a user.
   void login(String userName) {
     _userName = userName;
     notifyListeners();
   }
 
+  /// Logs out the current user.
   void logout() {
     _userName = '';
     notifyListeners();
   }
 }
 
+/// The login information.
 class LoginInfo2 extends ChangeNotifier {
-  var _userName = '';
+  /// The username of login.
   String get userName => _userName;
+  String _userName = '';
+
+  /// Whether a user has logged in.
   bool get loggedIn => _userName.isNotEmpty;
 
+  /// Logs in a user.
   Future<void> login(String userName) async {
     _userName = userName;
     notifyListeners();
     await Future<void>.delayed(const Duration(microseconds: 2500));
   }
 
+  /// Logs out the current user.
   Future<void> logout() async {
     _userName = '';
     notifyListeners();
@@ -116,16 +148,24 @@
   }
 }
 
+/// The relation of a person in a family.
 class FamilyPerson {
+  /// Creates a [FamilyPerson].
   FamilyPerson({required this.family, required this.person});
 
+  /// The family.
   final Family family;
+
+  /// the person.
   final Person person;
 }
 
+/// The repository.
 class Repository {
-  static final rnd = Random();
+  /// A random number generator.
+  static final Random rnd = Random();
 
+  /// Gets the families data.
   Future<List<Family>> getFamilies() async {
     // simulate network delay
     await Future<void>.delayed(const Duration(seconds: 1));
@@ -137,27 +177,35 @@
     return Families.data;
   }
 
+  /// Gets a family from the repository.
   Future<Family> getFamily(String fid) async =>
       (await getFamilies()).family(fid);
 
+  /// Gets a person from the repository.
   Future<FamilyPerson> getPerson(String fid, String pid) async {
-    final family = await getFamily(fid);
+    final Family family = await getFamily(fid);
     return FamilyPerson(family: family, person: family.person(pid));
   }
 }
 
+/// The repository.
 class Repository2 {
   Repository2._(this.userName);
+
+  /// The username.
   final String userName;
 
+  /// Gets a repository with the username.
   static Future<Repository2> get(String userName) async {
     // simulate network delay
     await Future<void>.delayed(const Duration(seconds: 1));
     return Repository2._(userName);
   }
 
-  static final rnd = Random();
+  /// A random number generator.
+  static final Random rnd = Random();
 
+  /// Gets the families data.
   Future<List<Family>> getFamilies() async {
     // simulate network delay
     await Future<void>.delayed(const Duration(seconds: 1));
@@ -169,40 +217,52 @@
     return Families.data;
   }
 
+  /// Gets a family from the repository.
   Future<Family> getFamily(String fid) async =>
       (await getFamilies()).family(fid);
 
+  /// Gets a person from the repository.
   Future<FamilyPerson> getPerson(String fid, String pid) async {
-    final family = await getFamily(fid);
+    final Family family = await getFamily(fid);
     return FamilyPerson(family: family, person: family.person(pid));
   }
 }
 
+/// A state stream.
 abstract class StateStream<T> {
+  /// Creates a [StateStream].
   StateStream();
 
+  /// Creates a [StateStream] with an initial value.
   StateStream.seeded(T value) : state = value {
     _controller.add(value);
   }
 
   final StreamController<T> _controller = StreamController<T>();
+
+  /// The state.
   late T state;
 
+  /// The [Stream] object.
   Stream<T> get stream => _controller.stream;
 
+  /// Pipes a new state into the stream.
   void emit(T state) {
     this.state = state;
     _controller.add(state);
   }
 
+  /// Disposes the stream.
   void dispose() {
     _controller.close();
   }
 }
 
+/// Stream for whether the user is currently logged in.
 class LoggedInState extends StateStream<bool> {
+  /// Creates a [LoggedInState].
   LoggedInState();
 
-  // ignore: avoid_positional_boolean_parameters
+  /// Creates a [LoggedInState] with an initial value.
   LoggedInState.seeded(bool value) : super.seeded(value);
 }
diff --git a/packages/go_router/example/lib/shared_scaffold.dart b/packages/go_router/example/lib/shared_scaffold.dart
index 2675ff6..8699f67 100644
--- a/packages/go_router/example/lib/shared_scaffold.dart
+++ b/packages/go_router/example/lib/shared_scaffold.dart
@@ -9,10 +9,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Shared Scaffold';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Shared Scaffold';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -21,30 +24,34 @@
         title: title,
       );
 
-  late final _router = GoRouter(
+  late final GoRouter _router = GoRouter(
     debugLogDiagnostics: true,
-    routes: [
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => _build(const Page1View()),
+        builder: (BuildContext context, GoRouterState state) =>
+            _build(const Page1View()),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => _build(const Page2View()),
+        builder: (BuildContext context, GoRouterState state) =>
+            _build(const Page2View()),
       ),
     ],
-    errorBuilder: (context, state) => _build(ErrorView(state.error!)),
+    errorBuilder: (BuildContext context, GoRouterState state) =>
+        _build(ErrorView(state.error!)),
 
     // use the navigatorBuilder to keep the SharedScaffold from being animated
     // as new pages as shown; wrappiong that in single-page Navigator at the
     // root provides an Overlay needed for the adaptive navigation scaffold and
     // a root Navigator to show the About box
-    navigatorBuilder: (context, state, child) => Navigator(
-      onPopPage: (route, dynamic result) {
+    navigatorBuilder:
+        (BuildContext context, GoRouterState state, Widget child) => Navigator(
+      onPopPage: (Route<dynamic> route, dynamic result) {
         route.didPop(result);
         return false; // don't pop the single page on the root navigator
       },
-      pages: [
+      pages: <Page<dynamic>>[
         MaterialPage<void>(
           child: state.error != null
               ? ErrorScaffold(body: child)
@@ -62,14 +69,19 @@
   Widget _build(Widget child) => Scaffold(body: child);
 }
 
+/// A scaffold with multiple pages.
 class SharedScaffold extends StatefulWidget {
+  /// Creates a shared scaffold.
   const SharedScaffold({
     required this.selectedIndex,
     required this.body,
     Key? key,
   }) : super(key: key);
 
+  /// The selected index
   final int selectedIndex;
+
+  /// The body of the page.
   final Widget body;
 
   @override
@@ -80,17 +92,19 @@
   @override
   Widget build(BuildContext context) => AdaptiveNavigationScaffold(
         selectedIndex: widget.selectedIndex,
-        destinations: const [
+        destinations: const <AdaptiveScaffoldDestination>[
           AdaptiveScaffoldDestination(title: 'Page 1', icon: Icons.first_page),
           AdaptiveScaffoldDestination(title: 'Page 2', icon: Icons.last_page),
           AdaptiveScaffoldDestination(title: 'About', icon: Icons.info),
         ],
         appBar: AdaptiveAppBar(title: const Text(App.title)),
-        navigationTypeResolver: (context) =>
+        navigationTypeResolver: (BuildContext context) =>
             _drawerSize ? NavigationType.drawer : NavigationType.bottom,
-        onDestinationSelected: (index) async {
+        onDestinationSelected: (int index) async {
           // if there's a drawer, close it
-          if (_drawerSize) Navigator.pop(context);
+          if (_drawerSize) {
+            Navigator.pop(context);
+          }
 
           switch (index) {
             case 0:
@@ -100,7 +114,7 @@
               context.go('/page2');
               break;
             case 2:
-              final packageInfo = await PackageInfo.fromPlatform();
+              final PackageInfo packageInfo = await PackageInfo.fromPlatform();
               showAboutDialog(
                 context: context,
                 applicationName: packageInfo.appName,
@@ -118,14 +132,16 @@
   bool get _drawerSize => MediaQuery.of(context).size.width >= 600;
 }
 
+/// The content of the first page.
 class Page1View extends StatelessWidget {
+  /// Creates a [Page1View].
   const Page1View({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) => Center(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
-          children: [
+          children: <Widget>[
             ElevatedButton(
               onPressed: () => context.go('/page2'),
               child: const Text('Go to page 2'),
@@ -135,14 +151,16 @@
       );
 }
 
+/// The content of the second page.
 class Page2View extends StatelessWidget {
+  /// Creates a [Page2View].
   const Page2View({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) => Center(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
-          children: [
+          children: <Widget>[
             ElevatedButton(
               onPressed: () => context.go('/'),
               child: const Text('Go to home page'),
@@ -152,13 +170,17 @@
       );
 }
 
+/// The error scaffold.
 class ErrorScaffold extends StatelessWidget {
+  /// Creates an [ErrorScaffold]
   const ErrorScaffold({
     required this.body,
     Key? key,
   }) : super(key: key);
 
+  /// The body of this scaffold.
   final Widget body;
+
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AdaptiveAppBar(title: const Text('Page Not Found')),
@@ -166,15 +188,19 @@
       );
 }
 
+/// A view to display error message.
 class ErrorView extends StatelessWidget {
+  /// Creates an [ErrorView].
   const ErrorView(this.error, {Key? key}) : super(key: key);
+
+  /// The error to display.
   final Exception error;
 
   @override
   Widget build(BuildContext context) => Center(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
-          children: [
+          children: <Widget>[
             SelectableText(error.toString()),
             TextButton(
               onPressed: () => context.go('/'),
diff --git a/packages/go_router/example/lib/state_restoration.dart b/packages/go_router/example/lib/state_restoration.dart
index bff77aa..695fa86 100644
--- a/packages/go_router/example/lib/state_restoration.dart
+++ b/packages/go_router/example/lib/state_restoration.dart
@@ -9,10 +9,13 @@
       const RootRestorationScope(restorationId: 'root', child: App()),
     );
 
+/// The main app.
 class App extends StatefulWidget {
+  /// Creates an [App].
   const App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: State Restoration';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: State Restoration';
 
   @override
   State<App> createState() => _AppState();
@@ -35,25 +38,29 @@
         restorationScopeId: 'app',
       );
 
-  final _router = GoRouter(
-    routes: [
+  final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       // restorationId set for the route automatically
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
       ),
 
       // restorationId set for the route automatically
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page2Screen(),
       ),
     ],
     restorationScopeId: 'router',
   );
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -62,7 +69,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/page2'),
                 child: const Text('Go to page 2'),
@@ -73,7 +80,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -82,7 +91,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/'),
                 child: const Text('Go to home page'),
diff --git a/packages/go_router/example/lib/sub_routes.dart b/packages/go_router/example/lib/sub_routes.dart
index 956876a..204fc30 100644
--- a/packages/go_router/example/lib/sub_routes.dart
+++ b/packages/go_router/example/lib/sub_routes.dart
@@ -9,10 +9,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Sub-routes';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Sub-routes';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -21,23 +24,25 @@
         title: title,
       );
 
-  final _router = GoRouter(
-    routes: [
+  final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => HomeScreen(families: Families.data),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            HomeScreen(families: Families.data),
+        routes: <GoRoute>[
           GoRoute(
             path: 'family/:fid',
-            builder: (context, state) => FamilyScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreen(
               family: Families.family(state.params['fid']!),
             ),
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 path: 'person/:pid',
-                builder: (context, state) {
-                  final family = Families.family(state.params['fid']!);
-                  final person = family.person(state.params['pid']!);
+                builder: (BuildContext context, GoRouterState state) {
+                  final Family family = Families.family(state.params['fid']!);
+                  final Person person = family.person(state.params['pid']!);
 
                   return PersonScreen(family: family, person: person);
                 },
@@ -50,16 +55,20 @@
   );
 }
 
+/// The home screen that shows a list of families.
 class HomeScreen extends StatelessWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({required this.families, Key? key}) : super(key: key);
+
+  /// The list of families.
   final List<Family> families;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: const Text(App.title)),
         body: ListView(
-          children: [
-            for (final f in families)
+          children: <Widget>[
+            for (final Family f in families)
               ListTile(
                 title: Text(f.name),
                 onTap: () => context.go('/family/${f.id}'),
@@ -69,16 +78,20 @@
       );
 }
 
+/// The screen that shows a list of persons in a family.
 class FamilyScreen extends StatelessWidget {
+  /// Creates a [FamilyScreen].
   const FamilyScreen({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: Text(family.name)),
         body: ListView(
-          children: [
-            for (final p in family.people)
+          children: <Widget>[
+            for (final Person p in family.people)
               ListTile(
                 title: Text(p.name),
                 onTap: () => context.go('/family/${family.id}/person/${p.id}'),
@@ -88,11 +101,16 @@
       );
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.family, required this.person, Key? key})
       : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
diff --git a/packages/go_router/example/lib/transitions.dart b/packages/go_router/example/lib/transitions.dart
index 4750a03..2ccbcef 100644
--- a/packages/go_router/example/lib/transitions.dart
+++ b/packages/go_router/example/lib/transitions.dart
@@ -7,10 +7,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Custom Transitions';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Custom Transitions';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -19,70 +22,88 @@
         title: title,
       );
 
-  final _router = GoRouter(
-    routes: [
+  final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
         redirect: (_) => '/none',
       ),
       GoRoute(
         path: '/fade',
-        pageBuilder: (context, state) => CustomTransitionPage<void>(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            CustomTransitionPage<void>(
           key: state.pageKey,
           child: const ExampleTransitionsScreen(
             kind: 'fade',
             color: Colors.red,
           ),
-          transitionsBuilder: (context, animation, secondaryAnimation, child) =>
+          transitionsBuilder: (BuildContext context,
+                  Animation<double> animation,
+                  Animation<double> secondaryAnimation,
+                  Widget child) =>
               FadeTransition(opacity: animation, child: child),
         ),
       ),
       GoRoute(
         path: '/scale',
-        pageBuilder: (context, state) => CustomTransitionPage<void>(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            CustomTransitionPage<void>(
           key: state.pageKey,
           child: const ExampleTransitionsScreen(
             kind: 'scale',
             color: Colors.green,
           ),
-          transitionsBuilder: (context, animation, secondaryAnimation, child) =>
+          transitionsBuilder: (BuildContext context,
+                  Animation<double> animation,
+                  Animation<double> secondaryAnimation,
+                  Widget child) =>
               ScaleTransition(scale: animation, child: child),
         ),
       ),
       GoRoute(
         path: '/slide',
-        pageBuilder: (context, state) => CustomTransitionPage<void>(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            CustomTransitionPage<void>(
           key: state.pageKey,
           child: const ExampleTransitionsScreen(
             kind: 'slide',
             color: Colors.yellow,
           ),
-          transitionsBuilder: (context, animation, secondaryAnimation, child) =>
+          transitionsBuilder: (BuildContext context,
+                  Animation<double> animation,
+                  Animation<double> secondaryAnimation,
+                  Widget child) =>
               SlideTransition(
-                  position: animation.drive(
-                    Tween<Offset>(
-                      begin: const Offset(0.25, 0.25),
-                      end: Offset.zero,
-                    ).chain(CurveTween(curve: Curves.easeIn)),
-                  ),
-                  child: child),
+            position: animation.drive(
+              Tween<Offset>(
+                begin: const Offset(0.25, 0.25),
+                end: Offset.zero,
+              ).chain(CurveTween(curve: Curves.easeIn)),
+            ),
+            child: child,
+          ),
         ),
       ),
       GoRoute(
         path: '/rotation',
-        pageBuilder: (context, state) => CustomTransitionPage<void>(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            CustomTransitionPage<void>(
           key: state.pageKey,
           child: const ExampleTransitionsScreen(
             kind: 'rotation',
             color: Colors.purple,
           ),
-          transitionsBuilder: (context, animation, secondaryAnimation, child) =>
+          transitionsBuilder: (BuildContext context,
+                  Animation<double> animation,
+                  Animation<double> secondaryAnimation,
+                  Widget child) =>
               RotationTransition(turns: animation, child: child),
         ),
       ),
       GoRoute(
         path: '/none',
-        pageBuilder: (context, state) => NoTransitionPage<void>(
+        pageBuilder: (BuildContext context, GoRouterState state) =>
+            NoTransitionPage<void>(
           key: state.pageKey,
           child: const ExampleTransitionsScreen(
             kind: 'none',
@@ -94,15 +115,28 @@
   );
 }
 
+/// An Example transitions screen.
 class ExampleTransitionsScreen extends StatelessWidget {
+  /// Creates an [ExampleTransitionsScreen].
   const ExampleTransitionsScreen({
     required this.color,
     required this.kind,
     Key? key,
   }) : super(key: key);
 
-  static final kinds = ['fade', 'scale', 'slide', 'rotation', 'none'];
+  /// The available transition kinds.
+  static final List<String> kinds = <String>[
+    'fade',
+    'scale',
+    'slide',
+    'rotation',
+    'none'
+  ];
+
+  /// The color of the container.
   final Color color;
+
+  /// The transition kind
   final String kind;
 
   @override
@@ -113,8 +147,8 @@
           child: Center(
             child: Column(
               mainAxisAlignment: MainAxisAlignment.center,
-              children: [
-                for (final kind in kinds)
+              children: <Widget>[
+                for (final String kind in kinds)
                   Padding(
                     padding: const EdgeInsets.all(8),
                     child: ElevatedButton(
diff --git a/packages/go_router/example/lib/url_strategy.dart b/packages/go_router/example/lib/url_strategy.dart
index 91fbcc1..f3b618a 100644
--- a/packages/go_router/example/lib/url_strategy.dart
+++ b/packages/go_router/example/lib/url_strategy.dart
@@ -15,10 +15,13 @@
   runApp(App());
 }
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: URL Path Strategy';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: URL Path Strategy';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -27,24 +30,28 @@
         title: App.title,
       );
 
-  final _router = GoRouter(
+  final GoRouter _router = GoRouter(
     // turn off the # in the URLs on the web
     urlPathStrategy: UrlPathStrategy.path,
 
-    routes: [
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page2Screen(),
       ),
     ],
   );
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -53,7 +60,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/page2'),
                 child: const Text('Go to page 2'),
@@ -64,7 +71,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -73,7 +82,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               ElevatedButton(
                 onPressed: () => context.go('/'),
                 child: const Text('Go to home page'),
diff --git a/packages/go_router/example/lib/user_input.dart b/packages/go_router/example/lib/user_input.dart
index 26af9d2..3054cb7 100644
--- a/packages/go_router/example/lib/user_input.dart
+++ b/packages/go_router/example/lib/user_input.dart
@@ -10,10 +10,13 @@
 
 void main() => runApp(App());
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: Navigator Integration';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: Navigator Integration';
 
   @override
   Widget build(BuildContext context) => MaterialApp.router(
@@ -23,34 +26,36 @@
         debugShowCheckedModeBanner: false,
       );
 
-  late final _router = GoRouter(
-    routes: [
+  late final GoRouter _router = GoRouter(
+    routes: <GoRoute>[
       GoRoute(
         name: 'home',
         path: '/',
-        builder: (context, state) => HomeScreen(families: Families.data),
-        routes: [
+        builder: (BuildContext context, GoRouterState state) =>
+            HomeScreen(families: Families.data),
+        routes: <GoRoute>[
           GoRoute(
             name: 'family',
             path: 'family/:fid',
-            builder: (context, state) => FamilyScreenWithAdd(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreenWithAdd(
               family: Families.family(state.params['fid']!),
             ),
-            routes: [
+            routes: <GoRoute>[
               GoRoute(
                 name: 'person',
                 path: 'person/:pid',
-                builder: (context, state) {
-                  final family = Families.family(state.params['fid']!);
-                  final person = family.person(state.params['pid']!);
+                builder: (BuildContext context, GoRouterState state) {
+                  final Family family = Families.family(state.params['fid']!);
+                  final Person person = family.person(state.params['pid']!);
                   return PersonScreen(family: family, person: person);
                 },
               ),
               GoRoute(
                 name: 'new-person',
                 path: 'new-person',
-                builder: (context, state) {
-                  final family = Families.family(state.params['fid']!);
+                builder: (BuildContext context, GoRouterState state) {
+                  final Family family = Families.family(state.params['fid']!);
                   return NewPersonScreen2(family: family);
                 },
               ),
@@ -62,27 +67,36 @@
   );
 }
 
+/// The home screen that shows a list of families.
 class HomeScreen extends StatelessWidget {
+  /// Creates a [HomeScreen].
   const HomeScreen({required this.families, Key? key}) : super(key: key);
+
+  /// The list of families.
   final List<Family> families;
 
   @override
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(title: const Text(App.title)),
         body: ListView(
-          children: [
-            for (final f in families)
+          children: <Widget>[
+            for (final Family f in families)
               ListTile(
                 title: Text(f.name),
-                onTap: () => context.goNamed('family', params: {'fid': f.id}),
+                onTap: () => context
+                    .goNamed('family', params: <String, String>{'fid': f.id}),
               )
           ],
         ),
       );
 }
 
+/// The family screen.
 class FamilyScreenWithAdd extends StatefulWidget {
+  /// Creates a [FamilyScreenWithAdd].
   const FamilyScreenWithAdd({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
@@ -94,7 +108,7 @@
   Widget build(BuildContext context) => Scaffold(
         appBar: AppBar(
           title: Text(widget.family.name),
-          actions: [
+          actions: <Widget>[
             IconButton(
               // onPressed: () => _addPerson1(context), // Navigator-style
               onPressed: () => _addPerson2(context), // GoRouter-style
@@ -104,14 +118,17 @@
           ],
         ),
         body: ListView(
-          children: [
-            for (final p in widget.family.people)
+          children: <Widget>[
+            for (final Person p in widget.family.people)
               ListTile(
                 title: Text(p.name),
                 onTap: () => context.go(context.namedLocation(
                   'person',
-                  params: {'fid': widget.family.id, 'pid': p.id},
-                  queryParams: {'qid': 'quid'},
+                  params: <String, String>{
+                    'fid': widget.family.id,
+                    'pid': p.id
+                  },
+                  queryParams: <String, String>{'qid': 'quid'},
                 )),
               ),
           ],
@@ -121,10 +138,11 @@
   // using a Navigator and a Navigator result
   // ignore: unused_element
   Future<void> _addPerson1(BuildContext context) async {
-    final person = await Navigator.push<Person>(
+    final Person? person = await Navigator.push<Person>(
       context,
-      MaterialPageRoute(
-        builder: (context) => NewPersonScreen1(family: widget.family),
+      MaterialPageRoute<Person>(
+        builder: (BuildContext context) =>
+            NewPersonScreen1(family: widget.family),
       ),
     );
 
@@ -132,7 +150,7 @@
       setState(() => widget.family.people.add(person));
 
       // ignore: use_build_context_synchronously
-      context.goNamed('person', params: {
+      context.goNamed('person', params: <String, String>{
         'fid': widget.family.id,
         'pid': person.id,
       });
@@ -141,15 +159,21 @@
 
   // using a GoRouter page
   void _addPerson2(BuildContext context) {
-    context.goNamed('new-person', params: {'fid': widget.family.id});
+    context.goNamed('new-person',
+        params: <String, String>{'fid': widget.family.id});
   }
 }
 
+/// The person screen.
 class PersonScreen extends StatelessWidget {
+  /// Creates a [PersonScreen].
   const PersonScreen({required this.family, required this.person, Key? key})
       : super(key: key);
 
+  /// The family this person belong to.
   final Family family;
+
+  /// The person to be displayed.
   final Person person;
 
   @override
@@ -160,8 +184,12 @@
 }
 
 // returning a Navigator result
+/// The screen to add a new person into the family.
 class NewPersonScreen1 extends StatefulWidget {
+  /// Creates a [NewPersonScreen1].
   const NewPersonScreen1({required this.family, Key? key}) : super(key: key);
+
+  /// The family to be added to.
   final Family family;
 
   @override
@@ -169,9 +197,9 @@
 }
 
 class _NewPersonScreen1State extends State<NewPersonScreen1> {
-  final _formKey = GlobalKey<FormState>();
-  final _nameController = TextEditingController();
-  final _ageController = TextEditingController();
+  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
+  final TextEditingController _nameController = TextEditingController();
+  final TextEditingController _ageController = TextEditingController();
 
   @override
   void dispose() {
@@ -195,24 +223,25 @@
                 width: 400,
                 child: Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
+                  children: <Widget>[
                     TextFormField(
                       controller: _nameController,
                       decoration: const InputDecoration(labelText: 'name'),
-                      validator: (value) => value == null || value.isEmpty
-                          ? 'Please enter a name'
-                          : null,
+                      validator: (String? value) =>
+                          value == null || value.isEmpty
+                              ? 'Please enter a name'
+                              : null,
                     ),
                     TextFormField(
                       controller: _ageController,
                       decoration: const InputDecoration(labelText: 'age'),
-                      validator: (value) => value == null ||
+                      validator: (String? value) => value == null ||
                               value.isEmpty ||
                               int.tryParse(value) == null
                           ? 'Please enter an age'
                           : null,
                     ),
-                    ButtonBar(children: [
+                    ButtonBar(children: <Widget>[
                       TextButton(
                         onPressed: () async {
                           // ask the user if they'd like to adandon their data
@@ -225,7 +254,7 @@
                       ElevatedButton(
                         onPressed: () {
                           if (_formKey.currentState!.validate()) {
-                            final person = Person(
+                            final Person person = Person(
                               id: 'p${widget.family.people.length + 1}',
                               name: _nameController.text,
                               age: int.parse(_ageController.text),
@@ -246,7 +275,7 @@
       );
 
   Future<bool> abandonNewPerson(BuildContext context) async {
-    final result = await showOkCancelAlertDialog(
+    final OkCancelResult result = await showOkCancelAlertDialog(
       context: context,
       title: 'Abandon New Person',
       message: 'Are you sure you abandon this new person?',
@@ -259,8 +288,12 @@
 }
 
 // adding the result to the data directly (GoRouter page)
+/// The screen to add a new person into the family.
 class NewPersonScreen2 extends StatefulWidget {
+  /// Creates a [NewPersonScreen1].
   const NewPersonScreen2({required this.family, Key? key}) : super(key: key);
+
+  /// The family to display.
   final Family family;
 
   @override
@@ -268,9 +301,9 @@
 }
 
 class _NewPersonScreen2State extends State<NewPersonScreen2> {
-  final _formKey = GlobalKey<FormState>();
-  final _nameController = TextEditingController();
-  final _ageController = TextEditingController();
+  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
+  final TextEditingController _nameController = TextEditingController();
+  final TextEditingController _ageController = TextEditingController();
 
   @override
   void dispose() {
@@ -294,24 +327,25 @@
                 width: 400,
                 child: Column(
                   crossAxisAlignment: CrossAxisAlignment.start,
-                  children: [
+                  children: <Widget>[
                     TextFormField(
                       controller: _nameController,
                       decoration: const InputDecoration(labelText: 'name'),
-                      validator: (value) => value == null || value.isEmpty
-                          ? 'Please enter a name'
-                          : null,
+                      validator: (String? value) =>
+                          value == null || value.isEmpty
+                              ? 'Please enter a name'
+                              : null,
                     ),
                     TextFormField(
                       controller: _ageController,
                       decoration: const InputDecoration(labelText: 'age'),
-                      validator: (value) => value == null ||
+                      validator: (String? value) => value == null ||
                               value.isEmpty ||
                               int.tryParse(value) == null
                           ? 'Please enter an age'
                           : null,
                     ),
-                    ButtonBar(children: [
+                    ButtonBar(children: <Widget>[
                       TextButton(
                         onPressed: () async {
                           // ask the user if they'd like to adandon their data
@@ -325,7 +359,7 @@
                       ElevatedButton(
                         onPressed: () {
                           if (_formKey.currentState!.validate()) {
-                            final person = Person(
+                            final Person person = Person(
                               id: 'p${widget.family.people.length + 1}',
                               name: _nameController.text,
                               age: int.parse(_ageController.text),
@@ -333,7 +367,7 @@
 
                             widget.family.people.add(person);
 
-                            context.goNamed('person', params: {
+                            context.goNamed('person', params: <String, String>{
                               'fid': widget.family.id,
                               'pid': person.id,
                             });
@@ -351,7 +385,7 @@
       );
 
   Future<bool> abandonNewPerson(BuildContext context) async {
-    final result = await showOkCancelAlertDialog(
+    final OkCancelResult result = await showOkCancelAlertDialog(
       context: context,
       title: 'Abandon New Person',
       message: 'Are you sure you abandon this new person?',
diff --git a/packages/go_router/example/lib/widgets_app.dart b/packages/go_router/example/lib/widgets_app.dart
index 595bb66..6474f3c 100644
--- a/packages/go_router/example/lib/widgets_app.dart
+++ b/packages/go_router/example/lib/widgets_app.dart
@@ -8,39 +8,46 @@
 
 void main() => runApp(App());
 
-const blue = Color(0xFF2196F3);
-const white = Color(0xFFFFFFFF);
+const Color _kBlue = Color(0xFF2196F3);
+const Color _kWhite = Color(0xFFFFFFFF);
 
+/// The main app.
 class App extends StatelessWidget {
+  /// Creates an [App].
   App({Key? key}) : super(key: key);
 
-  static const title = 'GoRouter Example: WidgetsApp';
+  /// The title of the app.
+  static const String title = 'GoRouter Example: WidgetsApp';
 
   @override
   Widget build(BuildContext context) => WidgetsApp.router(
         routeInformationParser: _router.routeInformationParser,
         routerDelegate: _router.routerDelegate,
         title: title,
-        color: blue,
-        textStyle: const TextStyle(color: blue),
+        color: _kBlue,
+        textStyle: const TextStyle(color: _kBlue),
       );
 
-  final _router = GoRouter(
+  final GoRouter _router = GoRouter(
     debugLogDiagnostics: true,
-    routes: [
+    routes: <GoRoute>[
       GoRoute(
         path: '/',
-        builder: (context, state) => const Page1Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page1Screen(),
       ),
       GoRoute(
         path: '/page2',
-        builder: (context, state) => const Page2Screen(),
+        builder: (BuildContext context, GoRouterState state) =>
+            const Page2Screen(),
       ),
     ],
   );
 }
 
+/// The screen of the first page.
 class Page1Screen extends StatelessWidget {
+  /// Creates a [Page1Screen].
   const Page1Screen({Key? key}) : super(key: key);
 
   @override
@@ -48,7 +55,7 @@
         child: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               const Text(
                 App.title,
                 style: TextStyle(fontWeight: FontWeight.bold),
@@ -58,7 +65,7 @@
                 onPressed: () => context.go('/page2'),
                 child: const Text(
                   'Go to page 2',
-                  style: TextStyle(color: white),
+                  style: TextStyle(color: _kWhite),
                 ),
               ),
             ],
@@ -67,7 +74,9 @@
       );
 }
 
+/// The screen of the second page.
 class Page2Screen extends StatelessWidget {
+  /// Creates a [Page2Screen].
   const Page2Screen({Key? key}) : super(key: key);
 
   @override
@@ -75,7 +84,7 @@
         child: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               const Text(
                 App.title,
                 style: TextStyle(fontWeight: FontWeight.bold),
@@ -85,7 +94,7 @@
                 onPressed: () => context.go('/'),
                 child: const Text(
                   'Go to home page',
-                  style: TextStyle(color: white),
+                  style: TextStyle(color: _kWhite),
                 ),
               ),
             ],
@@ -94,14 +103,19 @@
       );
 }
 
+/// A custom button.
 class Button extends StatelessWidget {
+  /// Creates a [Button].
   const Button({
     required this.onPressed,
     required this.child,
     Key? key,
   }) : super(key: key);
 
+  /// Called when user pressed the button.
   final VoidCallback onPressed;
+
+  /// The child subtree.
   final Widget child;
 
   @override
@@ -109,7 +123,7 @@
         onTap: onPressed,
         child: Container(
           padding: const EdgeInsets.all(8),
-          color: blue,
+          color: _kBlue,
           child: child,
         ),
       );
diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart
index 5a3150e..b331c61 100644
--- a/packages/go_router/lib/go_router.dart
+++ b/packages/go_router/lib/go_router.dart
@@ -26,8 +26,8 @@
   /// Get a location from route name and parameters.
   String namedLocation(
     String name, {
-    Map<String, String> params = const {},
-    Map<String, String> queryParams = const {},
+    Map<String, String> params = const <String, String>{},
+    Map<String, String> queryParams = const <String, String>{},
   }) =>
       GoRouter.of(this)
           .namedLocation(name, params: params, queryParams: queryParams);
@@ -39,8 +39,8 @@
   /// Navigate to a named route.
   void goNamed(
     String name, {
-    Map<String, String> params = const {},
-    Map<String, String> queryParams = const {},
+    Map<String, String> params = const <String, String>{},
+    Map<String, String> queryParams = const <String, String>{},
     Object? extra,
   }) =>
       GoRouter.of(this).goNamed(
@@ -57,8 +57,8 @@
   /// Navigate to a named route onto the page stack.
   void pushNamed(
     String name, {
-    Map<String, String> params = const {},
-    Map<String, String> queryParams = const {},
+    Map<String, String> params = const <String, String>{},
+    Map<String, String> queryParams = const <String, String>{},
     Object? extra,
   }) =>
       GoRouter.of(this).pushNamed(
diff --git a/packages/go_router/lib/src/go_route.dart b/packages/go_router/lib/src/go_route.dart
index e58dbdf..43c9123 100644
--- a/packages/go_router/lib/src/go_route.dart
+++ b/packages/go_router/lib/src/go_route.dart
@@ -19,7 +19,7 @@
     this.name,
     this.pageBuilder,
     this.builder = _builder,
-    this.routes = const [],
+    this.routes = const <GoRoute>[],
     this.redirect = _redirect,
   }) {
     if (path.isEmpty) {
@@ -34,9 +34,12 @@
     _pathRE = patternToRegExp(path, _pathParams);
 
     // check path params
-    final groupedParams = _pathParams.groupListsBy((p) => p);
-    final dupParams = Map<String, List<String>>.fromEntries(
-      groupedParams.entries.where((e) => e.value.length > 1),
+    final Map<String, List<String>> groupedParams =
+        _pathParams.groupListsBy<String>((String p) => p);
+    final Map<String, List<String>> dupParams =
+        Map<String, List<String>>.fromEntries(
+      groupedParams.entries
+          .where((MapEntry<String, List<String>> e) => e.value.length > 1),
     );
     if (dupParams.isNotEmpty) {
       throw Exception(
@@ -45,7 +48,7 @@
     }
 
     // check sub-routes
-    for (final route in routes) {
+    for (final GoRoute route in routes) {
       // check paths
       if (route.path != '/' &&
           (route.path.startsWith('/') || route.path.endsWith('/'))) {
@@ -56,7 +59,7 @@
     }
   }
 
-  final _pathParams = <String>[];
+  final List<String> _pathParams = <String>[];
   late final RegExp _pathRE;
 
   /// Optional name of the route.
@@ -70,7 +73,7 @@
   /// ```
   /// GoRoute(
   ///   path: '/',
-  ///   pageBuilder: (context, state) => MaterialPage<void>(
+  ///   pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage<void>(
   ///     key: state.pageKey,
   ///     child: HomePage(families: Families.data),
   ///   ),
@@ -84,7 +87,7 @@
   /// ```
   /// GoRoute(
   ///   path: '/',
-  ///   pageBuilder: (context, state) => MaterialPage<void>(
+  ///   pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage<void>(
   ///     key: state.pageKey,
   ///     child: HomePage(families: Families.data),
   ///   ),
@@ -101,7 +104,7 @@
   /// ```
   /// GoRoute(
   ///   path: '/',
-  ///   builder: (context, state) => FamilyPage(
+  ///   builder: (BuildContext context, GoRouterState state) => FamilyPage(
   ///     families: Families.family(
   ///       state.params['id'],
   ///     ),
@@ -126,30 +129,30 @@
   /// Can be represented as:
   ///
   /// ```
-  /// final _router = GoRouter(
-  ///   routes: [
+  /// final GoRouter _router = GoRouter(
+  ///   routes: <GoRoute>[
   ///     GoRoute(
   ///       path: '/',
-  ///       pageBuilder: (context, state) => MaterialPage<void>(
+  ///       pageBuilder: (BuildContext context, GoRouterState state) => MaterialPage<void>(
   ///         key: state.pageKey,
   ///         child: HomePage(families: Families.data),
   ///       ),
-  ///       routes: [
+  ///       routes: <GoRoute>[
   ///         GoRoute(
   ///           path: 'family/:fid',
-  ///           pageBuilder: (context, state) {
-  ///             final family = Families.family(state.params['fid']!);
+  ///           pageBuilder: (BuildContext context, GoRouterState state) {
+  ///             final Family family = Families.family(state.params['fid']!);
   ///             return MaterialPage<void>(
   ///               key: state.pageKey,
   ///               child: FamilyPage(family: family),
   ///             );
   ///           },
-  ///           routes: [
+  ///           routes: <GoRoute>[
   ///             GoRoute(
   ///               path: 'person/:pid',
-  ///               pageBuilder: (context, state) {
-  ///                 final family = Families.family(state.params['fid']!);
-  ///                 final person = family.person(state.params['pid']!);
+  ///               pageBuilder: (BuildContext context, GoRouterState state) {
+  ///                 final Family family = Families.family(state.params['fid']!);
+  ///                 final Person person = family.person(state.params['pid']!);
   ///                 return MaterialPage<void>(
   ///                   key: state.pageKey,
   ///                   child: PersonPage(family: family, person: person),
@@ -173,15 +176,15 @@
   ///
   /// For example:
   /// ```
-  /// final _router = GoRouter(
-  ///   routes: [
+  /// final GoRouter _router = GoRouter(
+  ///   routes: <GoRoute>[
   ///     GoRoute(
   ///       path: '/',
   ///       redirect: (_) => '/family/${Families.data[0].id}',
   ///     ),
   ///     GoRoute(
   ///       path: '/family/:fid',
-  ///       pageBuilder: (context, state) => ...,
+  ///       pageBuilder: (BuildContext context, GoRouterState state) => ...,
   ///     ),
   ///   ],
   /// );
diff --git a/packages/go_router/lib/src/go_route_information_parser.dart b/packages/go_router/lib/src/go_route_information_parser.dart
index c38b559..d5a7b15 100644
--- a/packages/go_router/lib/src/go_route_information_parser.dart
+++ b/packages/go_router/lib/src/go_route_information_parser.dart
@@ -14,7 +14,7 @@
   ) =>
       // Use [SynchronousFuture] so that the initial url is processed
       // synchronously and remove unwanted initial animations on deep-linking
-      SynchronousFuture(Uri.parse(routeInformation.location!));
+      SynchronousFuture<Uri>(Uri.parse(routeInformation.location!));
 
   /// for use by the Router architecture as part of the RouteInformationParser
   @override
diff --git a/packages/go_router/lib/src/go_route_match.dart b/packages/go_router/lib/src/go_route_match.dart
index d126fcb..e489043 100644
--- a/packages/go_router/lib/src/go_route_match.dart
+++ b/packages/go_router/lib/src/go_route_match.dart
@@ -27,7 +27,7 @@
         assert(fullpath.startsWith('/')),
         assert(Uri.parse(fullpath).queryParameters.isEmpty) {
     if (kDebugMode) {
-      for (final p in encodedParams.entries) {
+      for (final MapEntry<String, String> p in encodedParams.entries) {
         assert(p.value == Uri.encodeComponent(Uri.decodeComponent(p.value)),
             'encodedParams[${p.key}] is not encoded properly: "${p.value}"');
       }
@@ -47,27 +47,27 @@
     assert(route.name!.toLowerCase() == name.toLowerCase());
 
     // check that we have all the params we need
-    final paramNames = <String>[];
+    final List<String> paramNames = <String>[];
     patternToRegExp(fullpath, paramNames);
-    for (final paramName in paramNames) {
+    for (final String paramName in paramNames) {
       if (!params.containsKey(paramName)) {
         throw Exception('missing param "$paramName" for $fullpath');
       }
     }
 
     // check that we have don't have extra params
-    for (final key in params.keys) {
+    for (final String key in params.keys) {
       if (!paramNames.contains(key)) {
         throw Exception('unknown param "$key" for $fullpath');
       }
     }
 
-    final encodedParams = {
-      for (final param in params.entries)
+    final Map<String, String> encodedParams = <String, String>{
+      for (final MapEntry<String, String> param in params.entries)
         param.key: Uri.encodeComponent(param.value)
     };
 
-    final subloc = _locationFor(fullpath, encodedParams);
+    final String subloc = _locationFor(fullpath, encodedParams);
     return GoRouteMatch(
       route: route,
       subloc: subloc,
@@ -91,12 +91,14 @@
   }) {
     assert(!path.contains('//'));
 
-    final match = route.matchPatternAsPrefix(restLoc);
-    if (match == null) return null;
+    final RegExpMatch? match = route.matchPatternAsPrefix(restLoc);
+    if (match == null) {
+      return null;
+    }
 
-    final encodedParams = route.extractPathParams(match);
-    final pathLoc = _locationFor(path, encodedParams);
-    final subloc = GoRouterDelegate.fullLocFor(parentSubloc, pathLoc);
+    final Map<String, String> encodedParams = route.extractPathParams(match);
+    final String pathLoc = _locationFor(path, encodedParams);
+    final String subloc = GoRouterDelegate.fullLocFor(parentSubloc, pathLoc);
     return GoRouteMatch(
       route: route,
       subloc: subloc,
@@ -133,8 +135,8 @@
   final ValueKey<String>? pageKey;
 
   /// Parameters for the matched route, URI-decoded.
-  Map<String, String> get decodedParams => {
-        for (final param in encodedParams.entries)
+  Map<String, String> get decodedParams => <String, String>{
+        for (final MapEntry<String, String> param in encodedParams.entries)
           param.key: Uri.decodeComponent(param.value)
       };
 
diff --git a/packages/go_router/lib/src/go_router.dart b/packages/go_router/lib/src/go_router.dart
index ccc3b47..7ed7425 100644
--- a/packages/go_router/lib/src/go_router.dart
+++ b/packages/go_router/lib/src/go_router.dart
@@ -7,6 +7,7 @@
 import 'go_route.dart';
 import 'go_route_information_parser.dart';
 import 'go_router_delegate.dart';
+import 'go_router_state.dart';
 import 'inherited_go_router.dart';
 import 'logging.dart';
 import 'path_strategy_nonweb.dart'
@@ -36,7 +37,9 @@
     GoRouterNavigatorBuilder? navigatorBuilder,
     String? restorationScopeId,
   }) {
-    if (urlPathStrategy != null) setUrlPathStrategy(urlPathStrategy);
+    if (urlPathStrategy != null) {
+      setUrlPathStrategy(urlPathStrategy);
+    }
 
     setLogging(enabled: debugLogDiagnostics);
 
@@ -49,12 +52,17 @@
       refreshListenable: refreshListenable,
       routerNeglect: routerNeglect,
       initUri: Uri.parse(initialLocation),
-      observers: [...observers ?? [], this],
+      observers: <NavigatorObserver>[
+        ...observers ?? <NavigatorObserver>[],
+        this
+      ],
       debugLogDiagnostics: debugLogDiagnostics,
       restorationScopeId: restorationScopeId,
       // wrap the returned Navigator to enable GoRouter.of(context).go() et al,
       // allowing the caller to wrap the navigator themselves
-      builderWithNav: (context, state, nav) => InheritedGoRouter(
+      builderWithNav:
+          (BuildContext context, GoRouterState state, Navigator nav) =>
+              InheritedGoRouter(
         goRouter: this,
         child: navigatorBuilder?.call(context, state, nav) ?? nav,
       ),
@@ -62,7 +70,8 @@
   }
 
   /// The route information parser used by the go router.
-  final routeInformationParser = GoRouteInformationParser();
+  final GoRouteInformationParser routeInformationParser =
+      GoRouteInformationParser();
 
   /// The router delegate used by the go router.
   late final GoRouterDelegate routerDelegate;
@@ -74,8 +83,8 @@
   /// This is useful for redirecting to a named location.
   String namedLocation(
     String name, {
-    Map<String, String> params = const {},
-    Map<String, String> queryParams = const {},
+    Map<String, String> params = const <String, String>{},
+    Map<String, String> queryParams = const <String, String>{},
   }) =>
       routerDelegate.namedLocation(
         name,
@@ -93,8 +102,8 @@
   /// Navigate to the named route.
   void goNamed(
     String name, {
-    Map<String, String> params = const {},
-    Map<String, String> queryParams = const {},
+    Map<String, String> params = const <String, String>{},
+    Map<String, String> queryParams = const <String, String>{},
     Object? extra,
   }) =>
       go(
@@ -111,8 +120,8 @@
   /// `name='person', params={'fid': 'f2', 'pid': 'p1'}`
   void pushNamed(
     String name, {
-    Map<String, String> params = const {},
-    Map<String, String> queryParams = const {},
+    Map<String, String> params = const <String, String>{},
+    Map<String, String> queryParams = const <String, String>{},
     Object? extra,
   }) =>
       push(
@@ -132,7 +141,7 @@
 
   /// Find the current GoRouter in the widget tree.
   static GoRouter of(BuildContext context) {
-    final inherited =
+    final InheritedGoRouter? inherited =
         context.dependOnInheritedWidgetOfExactType<InheritedGoRouter>();
     assert(inherited != null, 'No GoRouter found in context');
     return inherited!.goRouter;
diff --git a/packages/go_router/lib/src/go_router_cupertino.dart b/packages/go_router/lib/src/go_router_cupertino.dart
index a356ffb..0314718 100644
--- a/packages/go_router/lib/src/go_router_cupertino.dart
+++ b/packages/go_router/lib/src/go_router_cupertino.dart
@@ -42,7 +42,7 @@
         child: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               Text(error?.toString() ?? 'page not found'),
               CupertinoButton(
                 onPressed: () => context.go('/'),
diff --git a/packages/go_router/lib/src/go_router_delegate.dart b/packages/go_router/lib/src/go_router_delegate.dart
index 38d2fee..791fb77 100644
--- a/packages/go_router/lib/src/go_router_delegate.dart
+++ b/packages/go_router/lib/src/go_router_delegate.dart
@@ -40,7 +40,7 @@
     this.restorationScopeId,
   }) {
     // check top-level route paths are valid
-    for (final route in routes) {
+    for (final GoRoute route in routes) {
       if (!route.path.startsWith('/')) {
         throw Exception('top-level path must start with "/": ${route.path}');
       }
@@ -95,21 +95,21 @@
   /// its history.
   final String? restorationScopeId;
 
-  final _key = GlobalKey<NavigatorState>();
-  final List<GoRouteMatch> _matches = [];
-  final _namedMatches = <String, GoRouteMatch>{};
-  final _pushCounts = <String, int>{};
+  final GlobalKey<NavigatorState> _key = GlobalKey<NavigatorState>();
+  final List<GoRouteMatch> _matches = <GoRouteMatch>[];
+  final Map<String, GoRouteMatch> _namedMatches = <String, GoRouteMatch>{};
+  final Map<String, int> _pushCounts = <String, int>{};
 
   void _cacheNamedRoutes(
     List<GoRoute> routes,
     String parentFullpath,
     Map<String, GoRouteMatch> namedFullpaths,
   ) {
-    for (final route in routes) {
-      final fullpath = fullLocFor(parentFullpath, route.path);
+    for (final GoRoute route in routes) {
+      final String fullpath = fullLocFor(parentFullpath, route.path);
 
       if (route.name != null) {
-        final name = route.name!.toLowerCase();
+        final String name = route.name!.toLowerCase();
         if (namedFullpaths.containsKey(name)) {
           throw Exception('duplication fullpaths for name "$name":'
               '${namedFullpaths[name]!.fullpath}, $fullpath');
@@ -117,12 +117,12 @@
 
         // we only have a partial match until we have a location;
         // we're really only caching the route and fullpath at this point
-        final match = GoRouteMatch(
+        final GoRouteMatch match = GoRouteMatch(
           route: route,
           subloc: '/TBD',
           fullpath: fullpath,
-          encodedParams: {},
-          queryParams: {},
+          encodedParams: <String, String>{},
+          queryParams: <String, String>{},
           extra: null,
           error: null,
         );
@@ -149,12 +149,14 @@
         '${queryParams.isEmpty ? '' : ', queryParams: $queryParams'}');
 
     // find route and build up the full path along the way
-    final match = _getNameRouteMatch(
+    final GoRouteMatch? match = _getNameRouteMatch(
       name.toLowerCase(), // case-insensitive name matching
       params: params,
       queryParams: queryParams,
     );
-    if (match == null) throw Exception('unknown route name: $name');
+    if (match == null) {
+      throw Exception('unknown route name: $name');
+    }
 
     assert(identical(match.queryParams, queryParams));
     return _addQueryParams(match.subloc, queryParams);
@@ -225,7 +227,7 @@
   Future<void> setInitialRoutePath(Uri configuration) {
     // if the initial location is /, then use the dev initial location;
     // otherwise, we're cruising to a deep link, so ignore dev initial location
-    final config = configuration.toString();
+    final String config = configuration.toString();
     if (config == '/') {
       _go(location);
     } else {
@@ -235,19 +237,20 @@
 
     // Use [SynchronousFuture] so that the initial url is processed
     // synchronously and remove unwanted initial animations on deep-linking
-    return SynchronousFuture(null);
+    return SynchronousFuture<void>(null);
   }
 
   /// For use by the Router architecture as part of the RouterDelegate.
   @override
   Future<void> setNewRoutePath(Uri configuration) async {
-    final config = configuration.toString();
+    final String config = configuration.toString();
     log.info('going to $config');
     _go(config);
   }
 
   void _go(String location, {Object? extra}) {
-    final matches = _getLocRouteMatchesWithRedirects(location, extra: extra);
+    final List<GoRouteMatch> matches =
+        _getLocRouteMatchesWithRedirects(location, extra: extra);
     assert(matches.isNotEmpty);
 
     // replace the stack of matches w/ the new ones
@@ -257,16 +260,17 @@
   }
 
   void _push(String location, {Object? extra}) {
-    final matches = _getLocRouteMatchesWithRedirects(location, extra: extra);
+    final List<GoRouteMatch> matches =
+        _getLocRouteMatchesWithRedirects(location, extra: extra);
     assert(matches.isNotEmpty);
-    final top = matches.last;
+    final GoRouteMatch top = matches.last;
 
     // remap the pageKey so allow any number of the same page on the stack
-    final fullpath = top.fullpath;
-    final count = (_pushCounts[fullpath] ?? 0) + 1;
+    final String fullpath = top.fullpath;
+    final int count = (_pushCounts[fullpath] ?? 0) + 1;
     _pushCounts[fullpath] = count;
-    final pageKey = ValueKey('$fullpath-p$count');
-    final match = GoRouteMatch(
+    final ValueKey<String> pageKey = ValueKey<String>('$fullpath-p$count');
+    final GoRouteMatch match = GoRouteMatch(
       route: top.route,
       subloc: top.subloc,
       fullpath: top.fullpath,
@@ -291,9 +295,11 @@
 
     try {
       // watch redirects for loops
-      final redirects = [_canonicalUri(location)];
+      final List<String> redirects = <String>[_canonicalUri(location)];
       bool redirected(String? redir) {
-        if (redir == null) return false;
+        if (redir == null) {
+          return false;
+        }
 
         if (Uri.tryParse(redir) == null) {
           throw Exception('invalid redirect: $redir');
@@ -301,13 +307,14 @@
 
         if (redirects.contains(redir)) {
           redirects.add(redir);
-          final msg = 'redirect loop detected: ${redirects.join(' => ')}';
+          final String msg =
+              'redirect loop detected: ${redirects.join(' => ')}';
           throw Exception(msg);
         }
 
         redirects.add(redir);
         if (redirects.length - 1 > redirectLimit) {
-          final msg = 'too many redirects: ${redirects.join(' => ')}';
+          final String msg = 'too many redirects: ${redirects.join(' => ')}';
           throw Exception(msg);
         }
 
@@ -317,10 +324,10 @@
 
       // keep looping till we're done redirecting
       for (;;) {
-        final loc = redirects.last;
+        final String loc = redirects.last;
 
         // check for top-level redirect
-        final uri = Uri.parse(loc);
+        final Uri uri = Uri.parse(loc);
         if (redirected(
           topRedirect(
             GoRouterState(
@@ -333,15 +340,17 @@
               queryParams: uri.queryParameters,
             ),
           ),
-        )) continue;
+        )) {
+          continue;
+        }
 
         // get stack of route matches
         matches = _getLocRouteMatches(loc, extra: extra);
 
         // merge new params to keep params from previously matched paths, e.g.
         // /family/:fid/person/:pid provides fid and pid to person/:pid
-        var previouslyMatchedParams = <String, String>{};
-        for (final match in matches) {
+        Map<String, String> previouslyMatchedParams = <String, String>{};
+        for (final GoRouteMatch match in matches) {
           assert(
             !previouslyMatchedParams.keys.any(match.encodedParams.containsKey),
             'Duplicated parameter names',
@@ -351,7 +360,7 @@
         }
 
         // check top route for redirect
-        final top = matches.last;
+        final GoRouteMatch top = matches.last;
         if (redirected(
           top.route.redirect(
             GoRouterState(
@@ -366,11 +375,15 @@
               extra: extra,
             ),
           ),
-        )) continue;
+        )) {
+          continue;
+        }
 
         // let Router know to update the address bar
         // (the initial route is not a redirect)
-        if (redirects.length > 1) notifyListeners();
+        if (redirects.length > 1) {
+          notifyListeners();
+        }
 
         // no more redirects!
         break;
@@ -384,19 +397,20 @@
       log.severe('Exception during GoRouter navigation', err, stack);
 
       // create a match that routes to the error page
-      final error = err is Exception ? err : Exception(err);
-      final uri = Uri.parse(location);
-      matches = [
+      final Exception error = err is Exception ? err : Exception(err);
+      final Uri uri = Uri.parse(location);
+      matches = <GoRouteMatch>[
         GoRouteMatch(
           subloc: uri.path,
           fullpath: uri.path,
-          encodedParams: {},
+          encodedParams: <String, String>{},
           queryParams: uri.queryParameters,
           extra: null,
           error: error,
           route: GoRoute(
             path: location,
-            pageBuilder: (context, state) => _errorPageBuilder(
+            pageBuilder: (BuildContext context, GoRouterState state) =>
+                _errorPageBuilder(
               context,
               GoRouterState(
                 this,
@@ -424,8 +438,8 @@
     String location, {
     Object? extra,
   }) {
-    final uri = Uri.parse(location);
-    final matchStacks = _getLocRouteMatchStacks(
+    final Uri uri = Uri.parse(location);
+    final List<List<GoRouteMatch>> matchStacks = _getLocRouteMatchStacks(
       loc: uri.path,
       restLoc: uri.path,
       routes: routes,
@@ -440,11 +454,12 @@
     }
 
     if (matchStacks.length > 1) {
-      final sb = StringBuffer()
+      final StringBuffer sb = StringBuffer()
         ..writeln('too many routes for location: $location');
 
-      for (final stack in matchStacks) {
-        sb.writeln('\t${stack.map((m) => m.route.path).join(' => ')}');
+      for (final List<GoRouteMatch> stack in matchStacks) {
+        sb.writeln(
+            '\t${stack.map((GoRouteMatch m) => m.route.path).join(' => ')}');
       }
 
       throw Exception(sb.toString());
@@ -452,10 +467,10 @@
 
     if (kDebugMode) {
       assert(matchStacks.length == 1);
-      final match = matchStacks.first.last;
-      final loc1 = _addQueryParams(match.subloc, match.queryParams);
-      final uri2 = Uri.parse(location);
-      final loc2 = _addQueryParams(uri2.path, uri2.queryParameters);
+      final GoRouteMatch match = matchStacks.first.last;
+      final String loc1 = _addQueryParams(match.subloc, match.queryParams);
+      final Uri uri2 = Uri.parse(location);
+      final String loc2 = _addQueryParams(uri2.path, uri2.queryParameters);
 
       // NOTE: match the lower case, since subloc is canonicalized to match the
       // path case whereas the location can be any case
@@ -466,7 +481,7 @@
   }
 
   /// turns a list of routes into a list of routes match stacks for the location
-  /// e.g. routes: [
+  /// e.g. routes: <GoRoute>[
   ///   /
   ///     family/:fid
   ///   /login
@@ -519,9 +534,9 @@
     required Object? extra,
   }) sync* {
     // find the set of matches at this level of the tree
-    for (final route in routes) {
-      final fullpath = fullLocFor(parentFullpath, route.path);
-      final match = GoRouteMatch.match(
+    for (final GoRoute route in routes) {
+      final String fullpath = fullLocFor(parentFullpath, route.path);
+      final GoRouteMatch? match = GoRouteMatch.match(
         route: route,
         restLoc: restLoc,
         parentSubloc: parentSubloc,
@@ -530,28 +545,33 @@
         queryParams: queryParams,
         extra: extra,
       );
-      if (match == null) continue;
+      if (match == null) {
+        continue;
+      }
 
       // if we have a complete match, then return the matched route
       // NOTE: need a lower case match because subloc is canonicalized to match
       // the path case whereas the location can be of any case and still match
       if (match.subloc.toLowerCase() == loc.toLowerCase()) {
-        yield [match];
+        yield <GoRouteMatch>[match];
         continue;
       }
 
       // if we have a partial match but no sub-routes, bail
-      if (route.routes.isEmpty) continue;
+      if (route.routes.isEmpty) {
+        continue;
+      }
 
       // otherwise recurse
-      final childRestLoc =
+      final String childRestLoc =
           loc.substring(match.subloc.length + (match.subloc == '/' ? 0 : 1));
       assert(loc.startsWith(match.subloc));
       assert(restLoc.isNotEmpty);
 
       // if there's no sub-route matches, then we don't have a match for this
       // location
-      final subRouteMatchStacks = _getLocRouteMatchStacks(
+      final List<List<GoRouteMatch>> subRouteMatchStacks =
+          _getLocRouteMatchStacks(
         loc: loc,
         restLoc: childRestLoc,
         parentSubloc: match.subloc,
@@ -560,22 +580,24 @@
         queryParams: queryParams,
         extra: extra,
       ).toList();
-      if (subRouteMatchStacks.isEmpty) continue;
+      if (subRouteMatchStacks.isEmpty) {
+        continue;
+      }
 
       // add the match to each of the sub-route match stacks and return them
-      for (final stack in subRouteMatchStacks) {
-        yield [match, ...stack];
+      for (final List<GoRouteMatch> stack in subRouteMatchStacks) {
+        yield <GoRouteMatch>[match, ...stack];
       }
     }
   }
 
   GoRouteMatch? _getNameRouteMatch(
     String name, {
-    Map<String, String> params = const {},
-    Map<String, String> queryParams = const {},
+    Map<String, String> params = const <String, String>{},
+    Map<String, String> queryParams = const <String, String>{},
     Object? extra,
   }) {
-    final partialMatch = _namedMatches[name];
+    final GoRouteMatch? partialMatch = _namedMatches[name];
     return partialMatch == null
         ? null
         : GoRouteMatch.matchNamed(
@@ -633,8 +655,8 @@
 
       // if there's an error, show an error page
       error = err is Exception ? err : Exception(err);
-      final uri = Uri.parse(location);
-      pages = [
+      final Uri uri = Uri.parse(location);
+      pages = <Page<dynamic>>[
         _errorPageBuilder(
           context,
           GoRouterState(
@@ -659,7 +681,7 @@
     }
 
     // wrap the returned Navigator to enable GoRouter.of(context).go()
-    final uri = Uri.parse(location);
+    final Uri uri = Uri.parse(location);
     return builderWithNav(
       context,
       GoRouterState(
@@ -678,8 +700,10 @@
         key: _key, // needed to enable Android system Back button
         pages: pages!,
         observers: observers,
-        onPopPage: (route, dynamic result) {
-          if (!route.didPop(result)) return false;
+        onPopPage: (Route<dynamic> route, dynamic result) {
+          if (!route.didPop(result)) {
+            return false;
+          }
           pop();
           return true;
         },
@@ -689,7 +713,7 @@
 
   /// Get the stack of sub-routes that matches the location and turn it into a
   /// stack of pages, e.g.
-  /// routes: [
+  /// routes: <GoRoute>[
   ///   /
   ///     family/:fid
   ///       person/:pid
@@ -714,14 +738,14 @@
   ) sync* {
     assert(matches.isNotEmpty);
 
-    var params = <String, String>{};
-    for (final match in matches) {
+    Map<String, String> params = <String, String>{};
+    for (final GoRouteMatch match in matches) {
       // merge new params to keep params from previously matched paths, e.g.
       // /family/:fid/person/:pid provides fid and pid to person/:pid
-      params = {...params, ...match.decodedParams};
+      params = <String, String>{...params, ...match.decodedParams};
 
       // get a page from the builder and associate it with a sub-location
-      final state = GoRouterState(
+      final GoRouterState state = GoRouterState(
         this,
         location: location,
         subloc: match.subloc,
@@ -759,22 +783,23 @@
       assert(_errorBuilderForAppType == null);
 
       // can be null during testing
-      final elem = context is Element ? context : null;
+      final Element? elem = context is Element ? context : null;
 
       if (elem != null && isMaterialApp(elem)) {
         log.info('MaterialApp found');
         _pageBuilderForAppType = pageBuilderForMaterialApp;
-        _errorBuilderForAppType =
-            (c, s) => GoRouterMaterialErrorScreen(s.error);
+        _errorBuilderForAppType = (BuildContext c, GoRouterState s) =>
+            GoRouterMaterialErrorScreen(s.error);
       } else if (elem != null && isCupertinoApp(elem)) {
         log.info('CupertinoApp found');
         _pageBuilderForAppType = pageBuilderForCupertinoApp;
-        _errorBuilderForAppType =
-            (c, s) => GoRouterCupertinoErrorScreen(s.error);
+        _errorBuilderForAppType = (BuildContext c, GoRouterState s) =>
+            GoRouterCupertinoErrorScreen(s.error);
       } else {
         log.info('WidgetsApp assumed');
         _pageBuilderForAppType = pageBuilderForWidgetApp;
-        _errorBuilderForAppType = (c, s) => GoRouterErrorScreen(s.error);
+        _errorBuilderForAppType =
+            (BuildContext c, GoRouterState s) => GoRouterErrorScreen(s.error);
       }
     }
 
@@ -793,7 +818,7 @@
     return _pageBuilderForAppType!(
       key: state.pageKey,
       name: state.name ?? state.fullpath,
-      arguments: {...state.params, ...state.queryParams},
+      arguments: <String, String>{...state.params, ...state.queryParams},
       restorationId: state.pageKey.value,
       child: builder(context, state),
     );
@@ -840,7 +865,7 @@
 
     if (_namedMatches.isNotEmpty) {
       log.info('known full paths for route names:');
-      for (final e in _namedMatches.entries) {
+      for (final MapEntry<String, GoRouteMatch> e in _namedMatches.entries) {
         log.info('  ${e.key} => ${e.value.fullpath}');
       }
     }
@@ -851,15 +876,15 @@
     String parentFullpath,
     int depth,
   ) {
-    for (final route in routes) {
-      final fullpath = fullLocFor(parentFullpath, route.path);
+    for (final GoRoute route in routes) {
+      final String fullpath = fullLocFor(parentFullpath, route.path);
       log.info('  => ${''.padLeft(depth * 2)}$fullpath');
       _outputFullPathsFor(route.routes, fullpath, depth + 1);
     }
   }
 
   static String _canonicalUri(String loc) {
-    var canon = Uri.parse(loc).toString();
+    String canon = Uri.parse(loc).toString();
     canon = canon.endsWith('?') ? canon.substring(0, canon.length - 1) : canon;
 
     // remove trailing slash except for when you shouldn't, e.g.
@@ -878,7 +903,7 @@
   }
 
   static String _addQueryParams(String loc, Map<String, String> queryParams) {
-    final uri = Uri.parse(loc);
+    final Uri uri = Uri.parse(loc);
     assert(uri.queryParameters.isEmpty);
     return _canonicalUri(
         Uri(path: uri.path, queryParameters: queryParams).toString());
diff --git a/packages/go_router/lib/src/go_router_error_page.dart b/packages/go_router/lib/src/go_router_error_page.dart
index 2300219..f9c1e68 100644
--- a/packages/go_router/lib/src/go_router_error_page.dart
+++ b/packages/go_router/lib/src/go_router_error_page.dart
@@ -15,14 +15,14 @@
   /// The exception to be displayed.
   final Exception? error;
 
-  static const _white = Color(0xFFFFFFFF);
+  static const Color _kWhite = Color(0xFFFFFFFF);
 
   @override
   Widget build(BuildContext context) => SafeArea(
         child: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               const Text(
                 'Page Not Found',
                 style: TextStyle(fontWeight: FontWeight.bold),
@@ -34,7 +34,7 @@
                 onPressed: () => context.go('/'),
                 child: const Text(
                   'Go to home page',
-                  style: TextStyle(color: _white),
+                  style: TextStyle(color: _kWhite),
                 ),
               ),
             ],
@@ -51,6 +51,8 @@
   }) : super(key: key);
 
   final VoidCallback onPressed;
+
+  /// The child subtree.
   final Widget child;
 
   @override
diff --git a/packages/go_router/lib/src/go_router_material.dart b/packages/go_router/lib/src/go_router_material.dart
index 7a949de..1b01920 100644
--- a/packages/go_router/lib/src/go_router_material.dart
+++ b/packages/go_router/lib/src/go_router_material.dart
@@ -41,7 +41,7 @@
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [
+            children: <Widget>[
               SelectableText(error?.toString() ?? 'page not found'),
               TextButton(
                 onPressed: () => context.go('/'),
diff --git a/packages/go_router/lib/src/go_router_refresh_stream.dart b/packages/go_router/lib/src/go_router_refresh_stream.dart
index 5452252..7860640 100644
--- a/packages/go_router/lib/src/go_router_refresh_stream.dart
+++ b/packages/go_router/lib/src/go_router_refresh_stream.dart
@@ -27,14 +27,14 @@
   ///
   /// Every time the [stream] receives an event the [GoRouter] will refresh its
   /// current route.
-  GoRouterRefreshStream(Stream stream) {
+  GoRouterRefreshStream(Stream<dynamic> stream) {
     notifyListeners();
     _subscription = stream.asBroadcastStream().listen(
           (dynamic _) => notifyListeners(),
         );
   }
 
-  late final StreamSubscription _subscription;
+  late final StreamSubscription<dynamic> _subscription;
 
   @override
   void dispose() {
diff --git a/packages/go_router/lib/src/go_router_state.dart b/packages/go_router/lib/src/go_router_state.dart
index ea3ac98..ffcb072 100644
--- a/packages/go_router/lib/src/go_router_state.dart
+++ b/packages/go_router/lib/src/go_router_state.dart
@@ -16,13 +16,13 @@
     required this.name,
     this.path,
     this.fullpath,
-    this.params = const {},
-    this.queryParams = const {},
+    this.params = const <String, String>{},
+    this.queryParams = const <String, String>{},
     this.extra,
     this.error,
     ValueKey<String>? pageKey,
   })  : pageKey = pageKey ??
-            ValueKey(error != null
+            ValueKey<String>(error != null
                 ? 'error'
                 : fullpath != null && fullpath.isNotEmpty
                     ? fullpath
@@ -65,8 +65,8 @@
   /// This is useful for redirecting to a named location.
   String namedLocation(
     String name, {
-    Map<String, String> params = const {},
-    Map<String, String> queryParams = const {},
+    Map<String, String> params = const <String, String>{},
+    Map<String, String> queryParams = const <String, String>{},
   }) =>
       _delegate.namedLocation(name, params: params, queryParams: queryParams);
 }
diff --git a/packages/go_router/lib/src/logging.dart b/packages/go_router/lib/src/logging.dart
index 9e8adb5..ccbb09b 100644
--- a/packages/go_router/lib/src/logging.dart
+++ b/packages/go_router/lib/src/logging.dart
@@ -8,21 +8,23 @@
 import 'package:logging/logging.dart';
 
 /// The logger for this package.
-final log = Logger('GoRouter');
+final Logger log = Logger('GoRouter');
 
-StreamSubscription? _subscription;
+StreamSubscription<LogRecord>? _subscription;
 
 /// Forwards diagnostic messages to the dart:developer log() API.
 void setLogging({bool enabled = false}) {
   _subscription?.cancel();
-  if (!enabled) return;
+  if (!enabled) {
+    return;
+  }
 
-  _subscription = log.onRecord.listen((e) {
+  _subscription = log.onRecord.listen((LogRecord e) {
     // use `dumpErrorToConsole` for severe messages to ensure that severe
     // exceptions are formatted consistently with other Flutter examples and
     // avoids printing duplicate exceptions
     if (e.level >= Level.SEVERE) {
-      final error = e.error;
+      final Object? error = e.error;
       FlutterError.dumpErrorToConsole(
         FlutterErrorDetails(
           exception: error is Exception ? error : Exception(error),
diff --git a/packages/go_router/lib/src/path_parser.dart b/packages/go_router/lib/src/path_parser.dart
index bb4d2e4..bf12633 100644
--- a/packages/go_router/lib/src/path_parser.dart
+++ b/packages/go_router/lib/src/path_parser.dart
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-final _parameterRegExp = RegExp(r':(\w+)(\((?:\\.|[^\\()])+\))?');
+final RegExp _parameterRegExp = RegExp(r':(\w+)(\((?:\\.|[^\\()])+\))?');
 
 /// Converts a [pattern] such as `/user/:id` into [RegExp].
 ///
@@ -90,7 +90,7 @@
 Map<String, String> extractPathParameters(
     List<String> parameters, RegExpMatch match) {
   return <String, String>{
-    for (var i = 0; i < parameters.length; ++i)
+    for (int i = 0; i < parameters.length; ++i)
       parameters[i]: match.namedGroup(parameters[i])!
   };
 }
diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml
index 1d65523..b340fad 100644
--- a/packages/go_router/pubspec.yaml
+++ b/packages/go_router/pubspec.yaml
@@ -1,7 +1,7 @@
 name: go_router
 description: A declarative router for Flutter based on Navigation 2 supporting
   deep linking, data-driven routes and more
-version: 3.0.3
+version: 3.0.4
 repository: https://github.com/flutter/packages/tree/main/packages/go_router
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22
 
diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart
index abb247f..3e55a1a 100644
--- a/packages/go_router/test/go_router_test.dart
+++ b/packages/go_router/test/go_router_test.dart
@@ -14,34 +14,38 @@
 import 'package:go_router/src/go_route_match.dart';
 import 'package:logging/logging.dart';
 
-const enableLogs = true;
-final log = Logger('GoRouter tests');
+const bool enableLogs = true;
+final Logger log = Logger('GoRouter tests');
 
 void main() {
-  if (enableLogs) Logger.root.onRecord.listen((e) => debugPrint('$e'));
+  if (enableLogs)
+    Logger.root.onRecord.listen((LogRecord e) => debugPrint('$e'));
 
   group('path routes', () {
     test('match home route', () {
-      final routes = [
-        GoRoute(path: '/', builder: (builder, state) => const HomeScreen()),
+      final List<GoRoute> routes = <GoRoute>[
+        GoRoute(
+            path: '/',
+            builder: (BuildContext context, GoRouterState state) =>
+                const HomeScreen()),
       ];
 
-      final router = _router(routes);
-      final matches = router.routerDelegate.matches;
+      final GoRouter router = _router(routes);
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(matches.first.fullpath, '/');
       expect(router.screenFor(matches.first).runtimeType, HomeScreen);
     });
 
     test('match too many routes', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(path: '/', builder: _dummy),
         GoRoute(path: '/', builder: _dummy),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(matches.first.fullpath, '/');
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
@@ -58,7 +62,7 @@
         GoRoute(
           path: '/',
           builder: _dummy,
-          routes: [
+          routes: <GoRoute>[
             GoRoute(
               path: '/foo',
               builder: _dummy,
@@ -73,7 +77,7 @@
         GoRoute(
           path: '/',
           builder: _dummy,
-          routes: [
+          routes: <GoRoute>[
             GoRoute(
               path: 'foo/',
               builder: _dummy,
@@ -85,7 +89,7 @@
 
     test('lack of leading / on top-level route', () {
       expect(() {
-        final routes = [
+        final List<GoRoute> routes = <GoRoute>[
           GoRoute(path: 'foo', builder: _dummy),
         ];
         _router(routes);
@@ -93,97 +97,106 @@
     });
 
     test('match no routes', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(path: '/', builder: _dummy),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/foo');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
     });
 
     test('match 2nd top level route', () {
-      final routes = [
-        GoRoute(path: '/', builder: (builder, state) => const HomeScreen()),
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
-            path: '/login', builder: (builder, state) => const LoginScreen()),
+            path: '/',
+            builder: (BuildContext context, GoRouterState state) =>
+                const HomeScreen()),
+        GoRoute(
+            path: '/login',
+            builder: (BuildContext context, GoRouterState state) =>
+                const LoginScreen()),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/login');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(matches.first.subloc, '/login');
       expect(router.screenFor(matches.first).runtimeType, LoginScreen);
     });
 
     test('match top level route when location has trailing /', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           path: '/login',
-          builder: (builder, state) => const LoginScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const LoginScreen(),
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/login/');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(matches.first.subloc, '/login');
       expect(router.screenFor(matches.first).runtimeType, LoginScreen);
     });
 
     test('match top level route when location has trailing / (2)', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(path: '/profile', redirect: (_) => '/profile/foo'),
         GoRoute(path: '/profile/:kind', builder: _dummy),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/profile/');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(matches.first.subloc, '/profile/foo');
       expect(router.screenFor(matches.first).runtimeType, DummyScreen);
     });
 
     test('match top level route when location has trailing / (3)', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(path: '/profile', redirect: (_) => '/profile/foo'),
         GoRoute(path: '/profile/:kind', builder: _dummy),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/profile/?bar=baz');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(matches.first.subloc, '/profile/foo');
       expect(router.screenFor(matches.first).runtimeType, DummyScreen);
     });
 
     test('match sub-route', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               path: 'login',
-              builder: (builder, state) => const LoginScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const LoginScreen(),
             ),
           ],
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/login');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches.length, 2);
       expect(matches.first.subloc, '/');
       expect(router.screenFor(matches.first).runtimeType, HomeScreen);
@@ -192,33 +205,36 @@
     });
 
     test('match sub-routes', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (context, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               path: 'family/:fid',
-              builder: (context, state) => const FamilyScreen('dummy'),
-              routes: [
+              builder: (BuildContext context, GoRouterState state) =>
+                  const FamilyScreen('dummy'),
+              routes: <GoRoute>[
                 GoRoute(
                   path: 'person/:pid',
-                  builder: (context, state) =>
+                  builder: (BuildContext context, GoRouterState state) =>
                       const PersonScreen('dummy', 'dummy'),
                 ),
               ],
             ),
             GoRoute(
               path: 'login',
-              builder: (context, state) => const LoginScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const LoginScreen(),
             ),
           ],
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       {
-        final matches = router.routerDelegate.matches;
+        final List<GoRouteMatch> matches = router.routerDelegate.matches;
         expect(matches, hasLength(1));
         expect(matches.first.fullpath, '/');
         expect(router.screenFor(matches.first).runtimeType, HomeScreen);
@@ -226,7 +242,7 @@
 
       router.go('/login');
       {
-        final matches = router.routerDelegate.matches;
+        final List<GoRouteMatch> matches = router.routerDelegate.matches;
         expect(matches.length, 2);
         expect(matches.first.subloc, '/');
         expect(router.screenFor(matches.first).runtimeType, HomeScreen);
@@ -236,7 +252,7 @@
 
       router.go('/family/f2');
       {
-        final matches = router.routerDelegate.matches;
+        final List<GoRouteMatch> matches = router.routerDelegate.matches;
         expect(matches.length, 2);
         expect(matches.first.subloc, '/');
         expect(router.screenFor(matches.first).runtimeType, HomeScreen);
@@ -246,7 +262,7 @@
 
       router.go('/family/f2/person/p1');
       {
-        final matches = router.routerDelegate.matches;
+        final List<GoRouteMatch> matches = router.routerDelegate.matches;
         expect(matches.length, 3);
         expect(matches.first.subloc, '/');
         expect(router.screenFor(matches.first).runtimeType, HomeScreen);
@@ -258,11 +274,11 @@
     });
 
     test('match too many sub-routes', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
           builder: _dummy,
-          routes: [
+          routes: <GoRoute>[
             GoRoute(
               path: 'foo/bar',
               builder: _dummy,
@@ -270,7 +286,7 @@
             GoRoute(
               path: 'foo',
               builder: _dummy,
-              routes: [
+              routes: <GoRoute>[
                 GoRoute(
                   path: 'bar',
                   builder: _dummy,
@@ -281,22 +297,27 @@
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/foo/bar');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
     });
 
     test('router state', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (builder, state) {
+          builder: (BuildContext context, GoRouterState state) {
             expect(
               state.location,
-              anyOf(['/', '/login', '/family/f2', '/family/f2/person/p1']),
+              anyOf(<String>[
+                '/',
+                '/login',
+                '/family/f2',
+                '/family/f2/person/p1'
+              ]),
             );
             expect(state.subloc, '/');
             expect(state.name, 'home');
@@ -307,11 +328,11 @@
             expect(state.extra! as int, 1);
             return const HomeScreen();
           },
-          routes: [
+          routes: <GoRoute>[
             GoRoute(
               name: 'login',
               path: 'login',
-              builder: (builder, state) {
+              builder: (BuildContext context, GoRouterState state) {
                 expect(state.location, '/login');
                 expect(state.subloc, '/login');
                 expect(state.name, 'login');
@@ -326,10 +347,10 @@
             GoRoute(
               name: 'family',
               path: 'family/:fid',
-              builder: (builder, state) {
+              builder: (BuildContext context, GoRouterState state) {
                 expect(
                   state.location,
-                  anyOf(['/family/f2', '/family/f2/person/p1']),
+                  anyOf(<String>['/family/f2', '/family/f2/person/p1']),
                 );
                 expect(state.subloc, '/family/f2');
                 expect(state.name, 'family');
@@ -340,11 +361,11 @@
                 expect(state.extra! as int, 3);
                 return FamilyScreen(state.params['fid']!);
               },
-              routes: [
+              routes: <GoRoute>[
                 GoRoute(
                   name: 'person',
                   path: 'person/:pid',
-                  builder: (context, state) {
+                  builder: (BuildContext context, GoRouterState state) {
                     expect(state.location, '/family/f2/person/p1');
                     expect(state.subloc, '/family/f2/person/p1');
                     expect(state.name, 'person');
@@ -366,7 +387,7 @@
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/', extra: 1);
       router.go('/login', extra: 2);
       router.go('/family/f2', extra: 3);
@@ -374,21 +395,23 @@
     });
 
     test('match path case insensitively', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           path: '/family/:fid',
-          builder: (builder, state) => FamilyScreen(state.params['fid']!),
+          builder: (BuildContext context, GoRouterState state) =>
+              FamilyScreen(state.params['fid']!),
         ),
       ];
 
-      final router = _router(routes);
-      const loc = '/FaMiLy/f2';
+      final GoRouter router = _router(routes);
+      const String loc = '/FaMiLy/f2';
       router.go(loc);
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
 
       // NOTE: match the lower case, since subloc is canonicalized to match the
       // path case whereas the location can be any case; so long as the path
@@ -400,14 +423,14 @@
     });
 
     test('match too many routes, ignoring case', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(path: '/page1', builder: _dummy),
         GoRoute(path: '/PaGe1', builder: _dummy),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/PAGE1');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
     });
@@ -415,19 +438,20 @@
 
   group('named routes', () {
     test('match home route', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
             name: 'home',
             path: '/',
-            builder: (builder, state) => const HomeScreen()),
+            builder: (BuildContext context, GoRouterState state) =>
+                const HomeScreen()),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.goNamed('home');
     });
 
     test('match too many routes', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(name: 'home', path: '/', builder: _dummy),
         GoRoute(name: 'home', path: '/', builder: _dummy),
       ];
@@ -445,95 +469,105 @@
 
     test('match no routes', () {
       expect(() {
-        final routes = [
+        final List<GoRoute> routes = <GoRoute>[
           GoRoute(name: 'home', path: '/', builder: _dummy),
         ];
-        final router = _router(routes);
+        final GoRouter router = _router(routes);
         router.goNamed('work');
       }, throwsException);
     });
 
     test('match 2nd top level route', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           name: 'login',
           path: '/login',
-          builder: (builder, state) => const LoginScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const LoginScreen(),
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.goNamed('login');
     });
 
     test('match sub-route', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               name: 'login',
               path: 'login',
-              builder: (builder, state) => const LoginScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const LoginScreen(),
             ),
           ],
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.goNamed('login');
     });
 
     test('match sub-route case insensitive', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               name: 'page1',
               path: 'page1',
-              builder: (builder, state) => const Page1Screen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const Page1Screen(),
             ),
             GoRoute(
               name: 'page2',
               path: 'Page2',
-              builder: (builder, state) => const Page2Screen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const Page2Screen(),
             ),
           ],
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.goNamed('Page1');
       router.goNamed('page2');
     });
 
     test('match w/ params', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (context, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               name: 'family',
               path: 'family/:fid',
-              builder: (context, state) => const FamilyScreen('dummy'),
-              routes: [
+              builder: (BuildContext context, GoRouterState state) =>
+                  const FamilyScreen('dummy'),
+              routes: <GoRoute>[
                 GoRoute(
                   name: 'person',
                   path: 'person/:pid',
-                  builder: (context, state) {
-                    expect(state.params, {'fid': 'f2', 'pid': 'p1'});
+                  builder: (BuildContext context, GoRouterState state) {
+                    expect(state.params,
+                        <String, String>{'fid': 'f2', 'pid': 'p1'});
                     return const PersonScreen('dummy', 'dummy');
                   },
                 ),
@@ -543,26 +577,29 @@
         ),
       ];
 
-      final router = _router(routes);
-      router.goNamed('person', params: {'fid': 'f2', 'pid': 'p1'});
+      final GoRouter router = _router(routes);
+      router.goNamed('person',
+          params: <String, String>{'fid': 'f2', 'pid': 'p1'});
     });
 
     test('too few params', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (context, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               name: 'family',
               path: 'family/:fid',
-              builder: (context, state) => const FamilyScreen('dummy'),
-              routes: [
+              builder: (BuildContext context, GoRouterState state) =>
+                  const FamilyScreen('dummy'),
+              routes: <GoRoute>[
                 GoRoute(
                   name: 'person',
                   path: 'person/:pid',
-                  builder: (context, state) =>
+                  builder: (BuildContext context, GoRouterState state) =>
                       const PersonScreen('dummy', 'dummy'),
                 ),
               ],
@@ -571,28 +608,31 @@
         ),
       ];
       expect(() {
-        final router = _router(routes);
-        router.goNamed('person', params: {'fid': 'f2'});
+        final GoRouter router = _router(routes);
+        router.goNamed('person', params: <String, String>{'fid': 'f2'});
       }, throwsException);
     });
 
     test('match case insensitive w/ params', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (context, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               name: 'family',
               path: 'family/:fid',
-              builder: (context, state) => const FamilyScreen('dummy'),
-              routes: [
+              builder: (BuildContext context, GoRouterState state) =>
+                  const FamilyScreen('dummy'),
+              routes: <GoRoute>[
                 GoRoute(
                   name: 'PeRsOn',
                   path: 'person/:pid',
-                  builder: (context, state) {
-                    expect(state.params, {'fid': 'f2', 'pid': 'p1'});
+                  builder: (BuildContext context, GoRouterState state) {
+                    expect(state.params,
+                        <String, String>{'fid': 'f2', 'pid': 'p1'});
                     return const PersonScreen('dummy', 'dummy');
                   },
                 ),
@@ -602,54 +642,59 @@
         ),
       ];
 
-      final router = _router(routes);
-      router.goNamed('person', params: {'fid': 'f2', 'pid': 'p1'});
+      final GoRouter router = _router(routes);
+      router.goNamed('person',
+          params: <String, String>{'fid': 'f2', 'pid': 'p1'});
     });
 
     test('too few params', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'family',
           path: '/family/:fid',
-          builder: (context, state) => const FamilyScreen('dummy'),
+          builder: (BuildContext context, GoRouterState state) =>
+              const FamilyScreen('dummy'),
         ),
       ];
       expect(() {
-        final router = _router(routes);
+        final GoRouter router = _router(routes);
         router.goNamed('family');
       }, throwsException);
     });
 
     test('too many params', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'family',
           path: '/family/:fid',
-          builder: (context, state) => const FamilyScreen('dummy'),
+          builder: (BuildContext context, GoRouterState state) =>
+              const FamilyScreen('dummy'),
         ),
       ];
       expect(() {
-        final router = _router(routes);
-        router.goNamed('family', params: {'fid': 'f2', 'pid': 'p1'});
+        final GoRouter router = _router(routes);
+        router.goNamed('family',
+            params: <String, String>{'fid': 'f2', 'pid': 'p1'});
       }, throwsException);
     });
 
     test('sparsely named routes', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
           redirect: (_) => '/family/f2',
         ),
         GoRoute(
           path: '/family/:fid',
-          builder: (context, state) => FamilyScreen(
+          builder: (BuildContext context, GoRouterState state) => FamilyScreen(
             state.params['fid']!,
           ),
-          routes: [
+          routes: <GoRoute>[
             GoRoute(
               name: 'person',
               path: 'person:pid',
-              builder: (context, state) => PersonScreen(
+              builder: (BuildContext context, GoRouterState state) =>
+                  PersonScreen(
                 state.params['fid']!,
                 state.params['pid']!,
               ),
@@ -658,57 +703,59 @@
         ),
       ];
 
-      final router = _router(routes);
-      router.goNamed('person', params: {'fid': 'f2', 'pid': 'p1'});
+      final GoRouter router = _router(routes);
+      router.goNamed('person',
+          params: <String, String>{'fid': 'f2', 'pid': 'p1'});
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(router.screenFor(matches.last).runtimeType, PersonScreen);
     });
 
     test('preserve path param spaces and slashes', () {
-      const param1 = 'param w/ spaces and slashes';
-      final routes = [
+      const String param1 = 'param w/ spaces and slashes';
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'page1',
           path: '/page1/:param1',
-          builder: (c, s) {
+          builder: (BuildContext c, GoRouterState s) {
             expect(s.params['param1'], param1);
             return const DummyScreen();
           },
         ),
       ];
 
-      final router = _router(routes);
-      final loc = router.namedLocation('page1', params: {'param1': param1});
+      final GoRouter router = _router(routes);
+      final String loc = router
+          .namedLocation('page1', params: <String, String>{'param1': param1});
       log.info('loc= $loc');
       router.go(loc);
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       log.info('param1= ${matches.first.decodedParams['param1']}');
       expect(router.screenFor(matches.first).runtimeType, DummyScreen);
       expect(matches.first.decodedParams['param1'], param1);
     });
 
     test('preserve query param spaces and slashes', () {
-      const param1 = 'param w/ spaces and slashes';
-      final routes = [
+      const String param1 = 'param w/ spaces and slashes';
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'page1',
           path: '/page1',
-          builder: (c, s) {
+          builder: (BuildContext c, GoRouterState s) {
             expect(s.queryParams['param1'], param1);
             return const DummyScreen();
           },
         ),
       ];
 
-      final router = _router(routes);
-      final loc =
-          router.namedLocation('page1', queryParams: {'param1': param1});
+      final GoRouter router = _router(routes);
+      final String loc = router.namedLocation('page1',
+          queryParams: <String, String>{'param1': param1});
       log.info('loc= $loc');
       router.go(loc);
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       log.info('param1= ${matches.first.queryParams['param1']}');
       expect(router.screenFor(matches.first).runtimeType, DummyScreen);
       expect(matches.first.queryParams['param1'], param1);
@@ -717,80 +764,90 @@
 
   group('redirects', () {
     test('top-level redirect', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
                 path: 'dummy',
-                builder: (builder, state) => const DummyScreen()),
+                builder: (BuildContext context, GoRouterState state) =>
+                    const DummyScreen()),
             GoRoute(
                 path: 'login',
-                builder: (builder, state) => const LoginScreen()),
+                builder: (BuildContext context, GoRouterState state) =>
+                    const LoginScreen()),
           ],
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
-        redirect: (state) => state.subloc == '/login' ? null : '/login',
+        redirect: (GoRouterState state) =>
+            state.subloc == '/login' ? null : '/login',
       );
       expect(router.location, '/login');
     });
 
     test('top-level redirect w/ named routes', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               name: 'dummy',
               path: 'dummy',
-              builder: (builder, state) => const DummyScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const DummyScreen(),
             ),
             GoRoute(
               name: 'login',
               path: 'login',
-              builder: (builder, state) => const LoginScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const LoginScreen(),
             ),
           ],
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         debugLogDiagnostics: true,
         routes: routes,
         errorBuilder: _dummy,
-        redirect: (state) =>
+        redirect: (GoRouterState state) =>
             state.subloc == '/login' ? null : state.namedLocation('login'),
       );
       expect(router.location, '/login');
     });
 
     test('route-level redirect', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               path: 'dummy',
-              builder: (builder, state) => const DummyScreen(),
-              redirect: (state) => '/login',
+              builder: (BuildContext context, GoRouterState state) =>
+                  const DummyScreen(),
+              redirect: (GoRouterState state) => '/login',
             ),
             GoRoute(
               path: 'login',
-              builder: (builder, state) => const LoginScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const LoginScreen(),
             ),
           ],
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
       );
@@ -799,28 +856,31 @@
     });
 
     test('route-level redirect w/ named routes', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           name: 'home',
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               name: 'dummy',
               path: 'dummy',
-              builder: (builder, state) => const DummyScreen(),
-              redirect: (state) => state.namedLocation('login'),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const DummyScreen(),
+              redirect: (GoRouterState state) => state.namedLocation('login'),
             ),
             GoRoute(
               name: 'login',
               path: 'login',
-              builder: (builder, state) => const LoginScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const LoginScreen(),
             ),
           ],
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
       );
@@ -829,45 +889,50 @@
     });
 
     test('multiple mixed redirect', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               path: 'dummy1',
-              builder: (builder, state) => const DummyScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const DummyScreen(),
             ),
             GoRoute(
               path: 'dummy2',
-              builder: (builder, state) => const DummyScreen(),
-              redirect: (state) => '/',
+              builder: (BuildContext context, GoRouterState state) =>
+                  const DummyScreen(),
+              redirect: (GoRouterState state) => '/',
             ),
           ],
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
-        redirect: (state) => state.subloc == '/dummy1' ? '/dummy2' : null,
+        redirect: (GoRouterState state) =>
+            state.subloc == '/dummy1' ? '/dummy2' : null,
       );
       router.go('/dummy1');
       expect(router.location, '/');
     });
 
     test('top-level redirect loop', () {
-      final router = GoRouter(
-        routes: [],
-        errorBuilder: (context, state) => ErrorScreen(state.error!),
-        redirect: (state) => state.subloc == '/'
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[],
+        errorBuilder: (BuildContext context, GoRouterState state) =>
+            ErrorScreen(state.error!),
+        redirect: (GoRouterState state) => state.subloc == '/'
             ? '/login'
             : state.subloc == '/login'
                 ? '/'
                 : null,
       );
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
       expect((router.screenFor(matches.first) as ErrorScreen).ex, isNotNull);
@@ -875,21 +940,22 @@
     });
 
     test('route-level redirect loop', () {
-      final router = GoRouter(
-        routes: [
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[
           GoRoute(
             path: '/',
-            redirect: (state) => '/login',
+            redirect: (GoRouterState state) => '/login',
           ),
           GoRoute(
             path: '/login',
-            redirect: (state) => '/',
+            redirect: (GoRouterState state) => '/',
           ),
         ],
-        errorBuilder: (context, state) => ErrorScreen(state.error!),
+        errorBuilder: (BuildContext context, GoRouterState state) =>
+            ErrorScreen(state.error!),
       );
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
       expect((router.screenFor(matches.first) as ErrorScreen).ex, isNotNull);
@@ -897,18 +963,20 @@
     });
 
     test('mixed redirect loop', () {
-      final router = GoRouter(
-        routes: [
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[
           GoRoute(
             path: '/login',
-            redirect: (state) => '/',
+            redirect: (GoRouterState state) => '/',
           ),
         ],
-        errorBuilder: (context, state) => ErrorScreen(state.error!),
-        redirect: (state) => state.subloc == '/' ? '/login' : null,
+        errorBuilder: (BuildContext context, GoRouterState state) =>
+            ErrorScreen(state.error!),
+        redirect: (GoRouterState state) =>
+            state.subloc == '/' ? '/login' : null,
       );
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
       expect((router.screenFor(matches.first) as ErrorScreen).ex, isNotNull);
@@ -916,17 +984,18 @@
     });
 
     test('top-level redirect loop w/ query params', () {
-      final router = GoRouter(
-        routes: [],
-        errorBuilder: (context, state) => ErrorScreen(state.error!),
-        redirect: (state) => state.subloc == '/'
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[],
+        errorBuilder: (BuildContext context, GoRouterState state) =>
+            ErrorScreen(state.error!),
+        redirect: (GoRouterState state) => state.subloc == '/'
             ? '/login?from=${state.location}'
             : state.subloc == '/login'
                 ? '/'
                 : null,
       );
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
       expect((router.screenFor(matches.first) as ErrorScreen).ex, isNotNull);
@@ -934,18 +1003,19 @@
     });
 
     test('expect null path/fullpath on top-level redirect', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           path: '/dummy',
-          redirect: (state) => '/',
+          redirect: (GoRouterState state) => '/',
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
         initialLocation: '/dummy',
@@ -954,23 +1024,25 @@
     });
 
     test('top-level redirect state', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           path: '/login',
-          builder: (builder, state) => const LoginScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const LoginScreen(),
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
         initialLocation: '/login?from=/',
         debugLogDiagnostics: true,
-        redirect: (state) {
+        redirect: (GoRouterState state) {
           expect(Uri.parse(state.location).queryParameters, isNotEmpty);
           expect(Uri.parse(state.subloc).queryParameters, isEmpty);
           expect(state.path, isNull);
@@ -982,59 +1054,60 @@
         },
       );
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, LoginScreen);
     });
 
     test('route-level redirect state', () {
-      const loc = '/book/0';
-      final routes = [
+      const String loc = '/book/0';
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/book/:bookId',
-          redirect: (state) {
+          redirect: (GoRouterState state) {
             expect(state.location, loc);
             expect(state.subloc, loc);
             expect(state.path, '/book/:bookId');
             expect(state.fullpath, '/book/:bookId');
-            expect(state.params, {'bookId': '0'});
+            expect(state.params, <String, String>{'bookId': '0'});
             expect(state.queryParams.length, 0);
             return null;
           },
-          builder: (c, s) => const HomeScreen(),
+          builder: (BuildContext c, GoRouterState s) => const HomeScreen(),
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
         initialLocation: loc,
         debugLogDiagnostics: true,
       );
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, HomeScreen);
     });
 
     test('sub-sub-route-level redirect params', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (c, s) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext c, GoRouterState s) => const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               path: 'family/:fid',
-              builder: (c, s) => FamilyScreen(s.params['fid']!),
-              routes: [
+              builder: (BuildContext c, GoRouterState s) =>
+                  FamilyScreen(s.params['fid']!),
+              routes: <GoRoute>[
                 GoRoute(
                   path: 'person/:pid',
-                  redirect: (s) {
+                  redirect: (GoRouterState s) {
                     expect(s.params['fid'], 'f2');
                     expect(s.params['pid'], 'p1');
                     return null;
                   },
-                  builder: (c, s) => PersonScreen(
+                  builder: (BuildContext c, GoRouterState s) => PersonScreen(
                     s.params['fid']!,
                     s.params['pid']!,
                   ),
@@ -1045,32 +1118,33 @@
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
         initialLocation: '/family/f2/person/p1',
         debugLogDiagnostics: true,
       );
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches.length, 3);
       expect(router.screenFor(matches.first).runtimeType, HomeScreen);
       expect(router.screenFor(matches[1]).runtimeType, FamilyScreen);
-      final page = router.screenFor(matches[2]) as PersonScreen;
+      final PersonScreen page = router.screenFor(matches[2]) as PersonScreen;
       expect(page.fid, 'f2');
       expect(page.pid, 'p1');
     });
 
     test('redirect limit', () {
-      final router = GoRouter(
-        routes: [],
-        errorBuilder: (context, state) => ErrorScreen(state.error!),
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[],
+        errorBuilder: (BuildContext context, GoRouterState state) =>
+            ErrorScreen(state.error!),
         debugLogDiagnostics: true,
-        redirect: (state) => '${state.location}+',
+        redirect: (GoRouterState state) => '${state.location}+',
         redirectLimit: 10,
       );
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(router.screenFor(matches.first).runtimeType, ErrorScreen);
       expect((router.screenFor(matches.first) as ErrorScreen).ex, isNotNull);
@@ -1080,20 +1154,22 @@
 
   group('initial location', () {
     test('initial location', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
+          routes: <GoRoute>[
             GoRoute(
               path: 'dummy',
-              builder: (builder, state) => const DummyScreen(),
+              builder: (BuildContext context, GoRouterState state) =>
+                  const DummyScreen(),
             ),
           ],
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
         initialLocation: '/dummy',
@@ -1102,18 +1178,19 @@
     });
 
     test('initial location w/ redirection', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           path: '/dummy',
-          redirect: (state) => '/',
+          redirect: (GoRouterState state) => '/',
         ),
       ];
 
-      final router = GoRouter(
+      final GoRouter router = GoRouter(
         routes: routes,
         errorBuilder: _dummy,
         initialLocation: '/dummy',
@@ -1124,22 +1201,24 @@
 
   group('params', () {
     test('preserve path param case', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           path: '/family/:fid',
-          builder: (builder, state) => FamilyScreen(state.params['fid']!),
+          builder: (BuildContext context, GoRouterState state) =>
+              FamilyScreen(state.params['fid']!),
         ),
       ];
 
-      final router = _router(routes);
-      for (final fid in ['f2', 'F2']) {
-        final loc = '/family/$fid';
+      final GoRouter router = _router(routes);
+      for (final String fid in <String>['f2', 'F2']) {
+        final String loc = '/family/$fid';
         router.go(loc);
-        final matches = router.routerDelegate.matches;
+        final List<GoRouteMatch> matches = router.routerDelegate.matches;
 
         expect(router.location, loc);
         expect(matches, hasLength(1));
@@ -1149,24 +1228,25 @@
     });
 
     test('preserve query param case', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           path: '/family',
-          builder: (builder, state) => FamilyScreen(
+          builder: (BuildContext context, GoRouterState state) => FamilyScreen(
             state.queryParams['fid']!,
           ),
         ),
       ];
 
-      final router = _router(routes);
-      for (final fid in ['f2', 'F2']) {
-        final loc = '/family?fid=$fid';
+      final GoRouter router = _router(routes);
+      for (final String fid in <String>['f2', 'F2']) {
+        final String loc = '/family?fid=$fid';
         router.go(loc);
-        final matches = router.routerDelegate.matches;
+        final List<GoRouteMatch> matches = router.routerDelegate.matches;
 
         expect(router.location, loc);
         expect(matches, hasLength(1));
@@ -1176,50 +1256,50 @@
     });
 
     test('preserve path param spaces and slashes', () {
-      const param1 = 'param w/ spaces and slashes';
-      final routes = [
+      const String param1 = 'param w/ spaces and slashes';
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/page1/:param1',
-          builder: (c, s) {
+          builder: (BuildContext c, GoRouterState s) {
             expect(s.params['param1'], param1);
             return const DummyScreen();
           },
         ),
       ];
 
-      final router = _router(routes);
-      final loc = '/page1/${Uri.encodeComponent(param1)}';
+      final GoRouter router = _router(routes);
+      final String loc = '/page1/${Uri.encodeComponent(param1)}';
       router.go(loc);
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       log.info('param1= ${matches.first.decodedParams['param1']}');
       expect(router.screenFor(matches.first).runtimeType, DummyScreen);
       expect(matches.first.decodedParams['param1'], param1);
     });
 
     test('preserve query param spaces and slashes', () {
-      const param1 = 'param w/ spaces and slashes';
-      final routes = [
+      const String param1 = 'param w/ spaces and slashes';
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/page1',
-          builder: (c, s) {
+          builder: (BuildContext c, GoRouterState s) {
             expect(s.queryParams['param1'], param1);
             return const DummyScreen();
           },
         ),
       ];
 
-      final router = _router(routes);
+      final GoRouter router = _router(routes);
       router.go('/page1?param1=$param1');
 
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(router.screenFor(matches.first).runtimeType, DummyScreen);
       expect(matches.first.queryParams['param1'], param1);
 
-      final loc = '/page1?param1=${Uri.encodeQueryComponent(param1)}';
+      final String loc = '/page1?param1=${Uri.encodeQueryComponent(param1)}';
       router.go(loc);
 
-      final matches2 = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches2 = router.routerDelegate.matches;
       expect(router.screenFor(matches2[0]).runtimeType, DummyScreen);
       expect(matches2[0].queryParams['param1'], param1);
     });
@@ -1227,13 +1307,14 @@
     test('error: duplicate path param', () {
       try {
         GoRouter(
-          routes: [
+          routes: <GoRoute>[
             GoRoute(
               path: '/:id/:blah/:bam/:id/:blah',
               builder: _dummy,
             ),
           ],
-          errorBuilder: (context, state) => ErrorScreen(state.error!),
+          errorBuilder: (BuildContext context, GoRouterState state) =>
+              ErrorScreen(state.error!),
           initialLocation: '/0/1/2/0/1',
         );
         expect(false, true);
@@ -1243,11 +1324,11 @@
     });
 
     test('duplicate query param', () {
-      final router = GoRouter(
-        routes: [
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[
           GoRoute(
             path: '/',
-            builder: (context, state) {
+            builder: (BuildContext context, GoRouterState state) {
               log.info('id= ${state.params['id']}');
               expect(state.params.length, 0);
               expect(state.queryParams.length, 1);
@@ -1256,24 +1337,25 @@
             },
           ),
         ],
-        errorBuilder: (context, state) => ErrorScreen(state.error!),
+        errorBuilder: (BuildContext context, GoRouterState state) =>
+            ErrorScreen(state.error!),
       );
 
       router.go('/?id=0&id=1');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(matches.first.fullpath, '/');
       expect(router.screenFor(matches.first).runtimeType, HomeScreen);
     });
 
     test('duplicate path + query param', () {
-      final router = GoRouter(
-        routes: [
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[
           GoRoute(
             path: '/:id',
-            builder: (context, state) {
-              expect(state.params, {'id': '0'});
-              expect(state.queryParams, {'id': '1'});
+            builder: (BuildContext context, GoRouterState state) {
+              expect(state.params, <String, String>{'id': '0'});
+              expect(state.queryParams, <String, String>{'id': '1'});
               return const HomeScreen();
             },
           ),
@@ -1282,25 +1364,27 @@
       );
 
       router.go('/0?id=1');
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
       expect(matches, hasLength(1));
       expect(matches.first.fullpath, '/:id');
       expect(router.screenFor(matches.first).runtimeType, HomeScreen);
     });
 
     test('push + query param', () {
-      final router = GoRouter(
-        routes: [
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[
           GoRoute(path: '/', builder: _dummy),
           GoRoute(
             path: '/family',
-            builder: (context, state) => FamilyScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreen(
               state.queryParams['fid']!,
             ),
           ),
           GoRoute(
             path: '/person',
-            builder: (context, state) => PersonScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                PersonScreen(
               state.queryParams['fid']!,
               state.queryParams['pid']!,
             ),
@@ -1311,29 +1395,31 @@
 
       router.go('/family?fid=f2');
       router.push('/person?fid=f2&pid=p1');
-      final page1 =
+      final FamilyScreen page1 =
           router.screenFor(router.routerDelegate.matches.first) as FamilyScreen;
       expect(page1.fid, 'f2');
 
-      final page2 =
+      final PersonScreen page2 =
           router.screenFor(router.routerDelegate.matches[1]) as PersonScreen;
       expect(page2.fid, 'f2');
       expect(page2.pid, 'p1');
     });
 
     test('push + extra param', () {
-      final router = GoRouter(
-        routes: [
+      final GoRouter router = GoRouter(
+        routes: <GoRoute>[
           GoRoute(path: '/', builder: _dummy),
           GoRoute(
             path: '/family',
-            builder: (context, state) => FamilyScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                FamilyScreen(
               (state.extra! as Map<String, String>)['fid']!,
             ),
           ),
           GoRoute(
             path: '/person',
-            builder: (context, state) => PersonScreen(
+            builder: (BuildContext context, GoRouterState state) =>
+                PersonScreen(
               (state.extra! as Map<String, String>)['fid']!,
               (state.extra! as Map<String, String>)['pid']!,
             ),
@@ -1342,33 +1428,35 @@
         errorBuilder: _dummy,
       );
 
-      router.go('/family', extra: {'fid': 'f2'});
-      router.push('/person', extra: {'fid': 'f2', 'pid': 'p1'});
-      final page1 =
+      router.go('/family', extra: <String, String>{'fid': 'f2'});
+      router.push('/person', extra: <String, String>{'fid': 'f2', 'pid': 'p1'});
+      final FamilyScreen page1 =
           router.screenFor(router.routerDelegate.matches.first) as FamilyScreen;
       expect(page1.fid, 'f2');
 
-      final page2 =
+      final PersonScreen page2 =
           router.screenFor(router.routerDelegate.matches[1]) as PersonScreen;
       expect(page2.fid, 'f2');
       expect(page2.pid, 'p1');
     });
 
     test('keep param in nested route', () {
-      final routes = [
+      final List<GoRoute> routes = <GoRoute>[
         GoRoute(
           path: '/',
-          builder: (builder, state) => const HomeScreen(),
+          builder: (BuildContext context, GoRouterState state) =>
+              const HomeScreen(),
         ),
         GoRoute(
           path: '/family/:fid',
-          builder: (builder, state) => FamilyScreen(state.params['fid']!),
-          routes: [
+          builder: (BuildContext context, GoRouterState state) =>
+              FamilyScreen(state.params['fid']!),
+          routes: <GoRoute>[
             GoRoute(
               path: 'person/:pid',
-              builder: (context, state) {
-                final fid = state.params['fid']!;
-                final pid = state.params['pid']!;
+              builder: (BuildContext context, GoRouterState state) {
+                final String fid = state.params['fid']!;
+                final String pid = state.params['pid']!;
 
                 return PersonScreen(fid, pid);
               },
@@ -1377,13 +1465,13 @@
         ),
       ];
 
-      final router = _router(routes);
-      const fid = "f1";
-      const pid = "p2";
-      final loc = "/family/$fid/person/$pid";
+      final GoRouter router = _router(routes);
+      const String fid = 'f1';
+      const String pid = 'p2';
+      const String loc = '/family/$fid/person/$pid';
 
       router.push(loc);
-      final matches = router.routerDelegate.matches;
+      final List<GoRouteMatch> matches = router.routerDelegate.matches;
 
       expect(router.location, loc);
       expect(matches, hasLength(2));
@@ -1398,7 +1486,7 @@
 
     setUpAll(() async {
       streamController = StreamController<int>.broadcast();
-      await streamController.addStream(Stream.value(0));
+      await streamController.addStream(Stream<int>.value(0));
     });
 
     tearDownAll(() {
@@ -1408,7 +1496,8 @@
     group('stream', () {
       test('no stream emits', () async {
         // Act
-        final notifyListener = MockGoRouterRefreshStream(
+        final MockGoRouterRefreshStream notifyListener =
+            MockGoRouterRefreshStream(
           streamController.stream,
         );
 
@@ -1421,14 +1510,15 @@
 
       test('three stream emits', () async {
         // Arrange
-        final toEmit = [1, 2, 3];
+        final List<int> toEmit = <int>[1, 2, 3];
 
         // Act
-        final notifyListener = MockGoRouterRefreshStream(
+        final MockGoRouterRefreshStream notifyListener =
+            MockGoRouterRefreshStream(
           streamController.stream,
         );
 
-        await streamController.addStream(Stream.fromIterable(toEmit));
+        await streamController.addStream(Stream<int>.fromIterable(toEmit));
 
         // Assert
         expect(notifyListener.notifyCount, equals(toEmit.length + 1));
@@ -1442,7 +1532,7 @@
 
 class MockGoRouterRefreshStream extends GoRouterRefreshStream {
   MockGoRouterRefreshStream(
-    Stream stream,
+    Stream<dynamic> stream,
   )   : notifyCount = 0,
         super(stream);
 
@@ -1457,7 +1547,8 @@
 
 GoRouter _router(List<GoRoute> routes) => GoRouter(
       routes: routes,
-      errorBuilder: (context, state) => ErrorScreen(state.error!),
+      errorBuilder: (BuildContext context, GoRouterState state) =>
+          ErrorScreen(state.error!),
       debugLogDiagnostics: true,
     );
 
@@ -1509,9 +1600,9 @@
 
 extension on GoRouter {
   Page<dynamic> _pageFor(GoRouteMatch match) {
-    final matches = routerDelegate.matches;
-    final i = matches.indexOf(match);
-    final pages =
+    final List<GoRouteMatch> matches = routerDelegate.matches;
+    final int i = matches.indexOf(match);
+    final List<Page<dynamic>> pages =
         routerDelegate.getPages(DummyBuildContext(), matches).toList();
     return pages[i];
   }
diff --git a/packages/go_router/test/path_parser_test.dart b/packages/go_router/test/path_parser_test.dart
index 85876ec..5d5ff89 100644
--- a/packages/go_router/test/path_parser_test.dart
+++ b/packages/go_router/test/path_parser_test.dart
@@ -7,7 +7,7 @@
 
 void main() {
   test('patternToRegExp without path parameter', () async {
-    final String pattern = '/settings/detail';
+    const String pattern = '/settings/detail';
     final List<String> pathParameter = <String>[];
     final RegExp regex = patternToRegExp(pattern, pathParameter);
     expect(pathParameter.isEmpty, isTrue);
@@ -20,7 +20,7 @@
   });
 
   test('patternToRegExp with path parameter', () async {
-    final String pattern = '/user/:id/book/:bookId';
+    const String pattern = '/user/:id/book/:bookId';
     final List<String> pathParameter = <String>[];
     final RegExp regex = patternToRegExp(pattern, pathParameter);
     expect(pathParameter.length, 2);
@@ -42,11 +42,11 @@
   });
 
   test('patternToPath without path parameter', () async {
-    final String pattern = '/settings/detail';
+    const String pattern = '/settings/detail';
     final List<String> pathParameter = <String>[];
     final RegExp regex = patternToRegExp(pattern, pathParameter);
 
-    final String url = '/settings/detail';
+    const String url = '/settings/detail';
     final RegExpMatch? match = regex.firstMatch(url);
     expect(match, isNotNull);
 
@@ -58,11 +58,11 @@
   });
 
   test('patternToPath with path parameter', () async {
-    final String pattern = '/user/:id/book/:bookId';
+    const String pattern = '/user/:id/book/:bookId';
     final List<String> pathParameter = <String>[];
     final RegExp regex = patternToRegExp(pattern, pathParameter);
 
-    final String url = '/user/123/book/456';
+    const String url = '/user/123/book/456';
     final RegExpMatch? match = regex.firstMatch(url);
     expect(match, isNotNull);