[go_router] [shell_route] Fix BottomNavigationBar might lost current index in long URIs. (#2636)

diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md
index 5d6e28f..537adf3 100644
--- a/packages/go_router/CHANGELOG.md
+++ b/packages/go_router/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 5.0.4
+
+- Fixes a bug in ShellRoute example where NavigationBar might lose current index in a nested routes.
+
 ## 5.0.3
 
 - Changes examples to use the routerConfig API
diff --git a/packages/go_router/example/lib/shell_route.dart b/packages/go_router/example/lib/shell_route.dart
index b33c0bb..8c73c83 100644
--- a/packages/go_router/example/lib/shell_route.dart
+++ b/packages/go_router/example/lib/shell_route.dart
@@ -77,6 +77,24 @@
               ),
             ],
           ),
+
+          /// The third screen to display in the bottom navigation bar.
+          GoRoute(
+            path: '/c',
+            builder: (BuildContext context, GoRouterState state) {
+              return const ScreenC();
+            },
+            routes: <RouteBase>[
+              // The details screen to display stacked on the inner Navigator.
+              // This will cover screen A but not the application shell.
+              GoRoute(
+                path: 'details',
+                builder: (BuildContext context, GoRouterState state) {
+                  return const DetailsScreen(label: 'C');
+                },
+              ),
+            ],
+          ),
         ],
       ),
     ],
@@ -121,6 +139,10 @@
             icon: Icon(Icons.business),
             label: 'B Screen',
           ),
+          BottomNavigationBarItem(
+            icon: Icon(Icons.notification_important_rounded),
+            label: 'C Screen',
+          ),
         ],
         currentIndex: _calculateSelectedIndex(context),
         onTap: (int idx) => _onItemTapped(idx, context),
@@ -131,12 +153,15 @@
   static int _calculateSelectedIndex(BuildContext context) {
     final GoRouter route = GoRouter.of(context);
     final String location = route.location;
-    if (location == '/a') {
+    if (location.startsWith('/a')) {
       return 0;
     }
-    if (location == '/b') {
+    if (location.startsWith('/b')) {
       return 1;
     }
+    if (location.startsWith('/c')) {
+      return 2;
+    }
     return 0;
   }
 
@@ -148,6 +173,9 @@
       case 1:
         GoRouter.of(context).go('/b');
         break;
+      case 2:
+        GoRouter.of(context).go('/c');
+        break;
     }
   }
 }
@@ -206,7 +234,34 @@
   }
 }
 
-/// The details screen for either the A or B screen.
+/// The third screen in the bottom navigation bar.
+class ScreenC extends StatelessWidget {
+  /// Constructs a [ScreenC] widget.
+  const ScreenC({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(),
+      body: Center(
+        child: Column(
+          mainAxisSize: MainAxisSize.min,
+          children: <Widget>[
+            const Text('Screen C'),
+            TextButton(
+              onPressed: () {
+                GoRouter.of(context).go('/c/details');
+              },
+              child: const Text('View C details'),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+/// The details screen for either the A, B or C screen.
 class DetailsScreen extends StatelessWidget {
   /// Constructs a [DetailsScreen].
   const DetailsScreen({
diff --git a/packages/go_router/example/test/shell_route_test.dart b/packages/go_router/example/test/shell_route_test.dart
new file mode 100644
index 0000000..9327189
--- /dev/null
+++ b/packages/go_router/example/test/shell_route_test.dart
@@ -0,0 +1,42 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:go_router_examples/shell_route.dart' as example;
+
+void main() {
+  testWidgets('example works', (WidgetTester tester) async {
+    await tester.pumpWidget(example.ShellRouteExampleApp());
+    expect(find.text('Screen A'), findsOneWidget);
+    // navigate to a/details
+    await tester.tap(find.text('View A details'));
+    await tester.pumpAndSettle();
+    expect(find.text('Details for A'), findsOneWidget);
+
+    // navigate to ScreenB
+    await tester.tap(find.text('B Screen'));
+    await tester.pumpAndSettle();
+    expect(find.text('Screen B'), findsOneWidget);
+
+    // navigate to b/details
+    await tester.tap(find.text('View B details'));
+    await tester.pumpAndSettle();
+    expect(find.text('Details for B'), findsOneWidget);
+
+    // back to ScreenB.
+    await tester.tap(find.byType(BackButton));
+    await tester.pumpAndSettle();
+
+    // navigate to ScreenC
+    await tester.tap(find.text('C Screen'));
+    await tester.pumpAndSettle();
+    expect(find.text('Screen C'), findsOneWidget);
+
+    // navigate to c/details
+    await tester.tap(find.text('View C details'));
+    await tester.pumpAndSettle();
+    expect(find.text('Details for C'), findsOneWidget);
+  });
+}
diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml
index 3f45de0..641d577 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: 5.0.3
+version: 5.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