flutter / flutter/flutter

[go_router] Browser back button unexpectedly navigates to an already replaced route that was the result of a redirection

Open
#159,200 7 comments 12 reactions 0 assignees View on GitHub
found in release: 3.24 found in release: 3.27 has reproducible steps p: go_router P2 package platform-web team-ecosystem triaged-ecosystem
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

### Steps to reproduce

1. Launch the sample
2. Tap the "Go to child screen" button
3. Wait 2 seconds for the deep link screen to forward you to the child screen
4. Being on the child screen, tap the browser's back button

### Expected results

You see the home screen

### Actual results

You see the deep link screen

### Code sample

Link to Dartpad
https://dartpad.dev/?id=72e8664b6408534f2448cc8a34199ee6

Code sample

```dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

// 1. The main file
void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp.router(routerConfig: goRouter);
}
}

// 2. The GoRouter configuration
final goRouter = GoRouter(
debugLogDiagnostics: kDebugMode,
routes: [
GoRoute(
path: '/',
builder: (context, state) => const SplashScreen(),
),
GoRoute(
path: '/home',
builder: (context, state) => const HomeScreen(),
),
GoRoute(
path: '/deeplink',
builder: (context, state) => const DeepLinkScreen(),
),
GoRoute(
path: '/child',
builder: (context, state) => const ChildScreen(),
redirect: (context, GoRouterState state) {
final valueAddedDuringDeepLink = state.uri.queryParameters['value'];
if (valueAddedDuringDeepLink == '42') {
return null;
} else {
return '/deeplink';
}
},
),
],
);

// 3. The 4 screens

// 3.1 Splash screen
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});

@override
State createState() => _SplashScreenState();
}

class _SplashScreenState extends State {
@override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 1), () {
context.go('/home');
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Splash screen')),
body: const Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Loading...'),
CircularProgressIndicator(),
],
)),
);
}
}

// 3.2 Home screen
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home screen')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Home'),
TextButton(
onPressed: () => context.push('/child'),
child: const Text('Go to child screen'),
),
],
)),
);
}
}

// 3.3 Deep link screen
class DeepLinkScreen extends StatefulWidget {
const DeepLinkScreen({super.key});

@override
State createState() => _DeepLinkScreenState();
}

class _DeepLinkScreenState extends State {
@override
void initState() {
super.initState();

Future.delayed(const Duration(seconds: 1), () {
context.pushReplacement('/child?value=42');
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Deep link screen')),
body: const Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Redirecting to the child screen...'),
CircularProgressIndicator(),
],
)));
}
}

// 3.4 Child screen
class ChildScreen extends StatelessWidget {
const ChildScreen({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Child screen')),
body: const Center(child: Text('Child')),
);
}
}
```

### Screenshots or Video

Screenshots / Video demonstration

https://github.com/user-attachments/assets/fcfe8c3e-bbe6-4747-b864-0039a2e858c9

### Logs

Logs

```console
Launching lib\main.dart on Chrome in debug mode...
Waiting for connection from debug service on Chrome...
This app is linked to the debug service: ws://127.0.0.1:63040/Dkr73jPlCtM=/ws
Debug service listening on ws://127.0.0.1:63040/Dkr73jPlCtM=/ws
Debug service listening on ws://127.0.0.1:63040/Dkr73jPlCtM=/ws
[GoRouter] Full paths for routes:
├─/ (SplashScreen)
├─/home (HomeScreen)
├─/deeplink (DeepLinkScreen)
└─/child (ChildScreen)

[GoRouter] setting initial location null
[GoRouter] Using MaterialApp configuration
[GoRouter] going to /home
[GoRouter] pushing /child
[GoRouter] redirecting to RouteMatchList#7876f(uri: /deeplink, matches: [RouteMatch#f0590(route: GoRoute#6038c(name: null, path: "/deeplink"))])
[GoRouter] pushReplacement /child?value=42
[GoRouter] pushing /child
[GoRouter] redirecting to RouteMatchList#7876f(uri: /deeplink, matches: [RouteMatch#f0590(route: GoRoute#6038c(name: null, path: "/deeplink"))])
[GoRouter] pushReplacement /child?value=42
[GoRouter] pushReplacement /child?value=42
```

### Flutter Doctor output

Doctor output

```console
PS G:\Projects\gorouter-playground> flutter doctor -v
[√] Flutter (Channel stable, 3.19.4, on Microsoft Windows [Version 10.0.22631.4460], locale en-US)
• Flutter version 3.19.4 on channel stable at C:\Development\SDKs\Flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 68bfaea224 (8 months ago), 2024-03-20 15:36:31 -0700
• Engine revision a5c24f538d
• Dart version 3.3.2
• DevTools version 2.31.1

[√] Windows Version (Installed version of Windows is version 10 or higher)

[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at C:\Development\SDKs\Android
• Platform android-34, build-tools 34.0.0
• ANDROID_HOME = C:\Development\SDKs\Android
• ANDROID_SDK_ROOT = C:\Development\SDKs\Android
• Java binary at: C:\Development\IDEs\AndroidStudioKoala\jbr\bin\java
• Java version OpenJDK Runtime Environment (build 17.0.11+0--11852314)
• All Android licenses accepted.

[√] Chrome - develop for the web
• Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.11.6)
• Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
• Visual Studio Community 2022 version 17.11.35431.28
• Windows 10 SDK version 10.0.22621.0

[√] Android Studio (version 2024.1)
• Android Studio at C:\Development\IDEs\AndroidStudioKoala
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.11+0--11852314)

[√] IntelliJ IDEA Community Edition (version 2022.1)
• IntelliJ at C:\Development\IDEs\IntelliJ IDEA\IntelliJ IDEA Community Edition 2020.3.2
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin version 221.6103.1

[√] Connected device (3 available)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.22631.4460]
• Chrome (web) • chrome • web-javascript • Google Chrome 131.0.6778.70
• Edge (web) • edge • web-javascript • Microsoft Edge 130.0.2849.68

[√] Network resources
• All expected network resources are available.

• No issues found!

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.