0

I am using go_router and got such config:

final router = GoRouter(
  initialLocation: '/',
  routes: [
    GoRoute(path: '/', pageBuilder: (context, state) => const MaterialPage(child: MyHomePage(title: 'Flutter Demo Home Page')),),
    GoRoute(path: '/second', pageBuilder: (context, state) => const MaterialPage(child: MyHomePage(title: 'Second !')),),
  ],
);

When I visit web directly using: /second page opens correctly, but there is no way to go back to: / (no back arrow in the App bar).

If I go to / and then open /second page via: context.push("/second"); then naturally back arrow is present.

When I type URI directly in the browser, how can I make sure that App bar back arrow allows me to go to the initial page?

Full example:

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

void main() {
  runApp(const MyApp());
}

final router = GoRouter(
  initialLocation: '/',
  routes: [
    GoRoute(path: '/', pageBuilder: (context, state) => const MaterialPage(child: MyHomePage(title: 'Flutter Demo Home Page')),),
    GoRoute(path: '/second', pageBuilder: (context, state) => const MaterialPage(child: MyHomePage(title: 'Second !')),),
  ],
);

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routerConfig: router,
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          context.push("/second");
        },
        tooltip: 'Navigate',
        child: const Icon(Icons.navigate_next),
      ),
    );
  }
}

Tom Raganowicz
  • 2,169
  • 5
  • 27
  • 41

2 Answers2

0

For back to root from app bar any where use this:

 Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.of(context, rootNavigator: true).pushAndRemoveUntil(
            MaterialPageRoute(
                builder: (context) => const  MyHomePage(title: 'Flutter Demo Home Page')),
            (route) => true);
        },
        tooltip: 'Navigate',
        child: const Icon(Icons.navigate_next),
      ),
    );
  }
}

You can use this code to back root:

  Navigator.of(context, rootNavigator: true).pushAndRemoveUntil(
            MaterialPageRoute(
                builder: (context) => const  MyHomePage(title: 'Flutter Demo Home Page')),
            (route) => true);
  • Well, in my case I can use: `context.go("/");`, but that's not the point. The point is to have the back arrow present in the App bar, as if the root was there. You answer disregards fact that I am using router. – Tom Raganowicz Feb 02 '23 at 10:35
  • What exactly do you mean? Do you want to return to the root or return to the previous page? – Mohammad Mirshahbazi Feb 02 '23 at 10:40
  • Ideally I would like to return to the root via `AppBar` as if it was the previous page. – Tom Raganowicz Feb 02 '23 at 10:44
  • I have updated the answer, the only way to return to the root from any page is this. Good luck – Mohammad Mirshahbazi Feb 02 '23 at 11:59
  • Thanks for your effort, but your answer doesn't really answer my question, it also uses Navigator approach which isn't remotely close to the router approach and your comment disregards the solution that I've added earlier on. – Tom Raganowicz Feb 02 '23 at 15:58
0

The solution is to nest routes e.g. like this:

routes: [
    GoRoute(path: '/', pageBuilder: (context, state) => const MaterialPage(child: MyHomePage(title: 'Flutter Demo Home Page')), routes: [
      GoRoute(path: 'second', pageBuilder: (context, state) => const MaterialPage(child: MyHomePage(title: 'Second !'))), 
    ]),
  ],

In which case when you visit: /second directly, the / page will be on the stack.

It is possible to test the "back arrow" behavior without web browser, by going to /second directly without pushing page on stack: context.go("/second");

Tom Raganowicz
  • 2,169
  • 5
  • 27
  • 41