go_router and deep linking
Navigator 1.0 is imperative: "open this screen", "go back". That model gets awkward once you need web URLs, deep links and non-trivial redirects, because the link between app state and the URL is maintained by hand.
Declarative routing (the Navigator 2.0 idea) inverts it: the URL is the source of truth and the screen stack is derived from it. In practice the most widely used implementation is `go_router`, because the raw Navigator 2.0 API is far too involved to use directly.
The three main benefits of go_router:
- A route hierarchy — you declare child routes, and when a deep link arrives the screens behind it are built automatically, so the back button behaves sensibly
- `redirect` — central redirection: sending an unauthenticated user from a protected route to login is written once rather than on every screen
- Typed parameters —
path: '/order/:id'withstate.pathParameters['id'], and full type safety via code generation if you want it
Interview tip. Do not answer "what is the difference between Navigator 1.0 and 2.0?" with "one is old, one is new". The difference is imperative versus declarative: in the first you issue commands, in the second you describe the state (the URL) and the stack is derived from it. Add the practical note: the raw Navigator 2.0 API is complex enough that real projects use go_router.
📚 Sources and documentation
- Deep linkingofficialdocs.flutter.dev
- go_router packageofficialpub.dev
Redirects, child routes and ShellRoute examples are covered in the README.
- Navigation and routingofficialdocs.flutter.dev