TLDR: Wrap the widget which needs to access to Navigator into a Builder or extract that sub-tree into a class. And use the new BuildContext to access Navigator.
This error is unrelated to the destination. It happens because you used a context that doesn't contain a Navigator instance as parent.
How do I create a Navigator instance then ?
This is usually done by inserting in your widget tree a MaterialApp or WidgetsApp. Although you can do it manually by using Navigator directly but less recommended. Then, all children of such widget can access NavigatorState using Navigator.of(context).
Wait, I already have a MaterialApp/WidgetsApp!
That's most likely the case. But this error can still happen when you use a context that is a parent of MaterialApp/WidgetsApp.
This happens because when you do Navigator.of(context), it will start from the widget associated to the context used, and then go upward in the widget tree until it either finds a Navigator or there's no more widgets to iterate through.
In the first case, everything is fine. In the second, it throws
Navigator operation requested with a context that does not include a Navigator.
So, how do I fix it ?
First, let's reproduce this error:
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Center( child: RaisedButton( child: Text("Foo"), onPressed: () => Navigator.pushNamed(context, "/"), ), ), ); } }
This example creates a button that attempts to go to '/' on click but will instead throw an exception.
Notice here that in the
onPressed: () => Navigator.pushNamed(context, "/"),
we used context passed by build of MyApp.
The problem is, MyApp is actually a parent of MaterialApp, as it's the widget who instantiates MaterialApp! Therefore, MyApp's BuildContext doesn't have a MaterialApp as parent.
To solve this problem, we need to use a different context.
In this situation, the easiest solution is to introduce a new widget as child of MaterialApp, and then use that widget's context to do the Navigator call.
There are a few ways to achieve this. You can extract home into a custom class:
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: MyHome() ); } } class MyHome extends StatelessWidget { @override Widget build(BuildContext context) { return Center( child: RaisedButton( child: Text("Foo"), onPressed: () => Navigator.pushNamed(context, "/"), ), ); } }
Or you can use Builder:
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Builder( builder: (context) => Center( child: RaisedButton( child: Text("Foo"), onPressed: () => Navigator.pushNamed(context, "/"), ), ), ), ); } }