NavigatorObserver: Listening to Route Changes in Flutter
A NavigatorObserver acts like a flight traffic controller for your app's screens, letting you react to navigation events like `push` and `pop`. It's used for analytics or updating UI based on the current route.
WHY IT EXISTS: Flutter's Navigator manages the stack of screens, but often you need to perform an action because a navigation event happened, like logging a screen view. NavigatorObserver provides a clean, decoupled way to listen for these events without modifying the navigation logic itself.
THE MENTAL MODEL: Think of NavigatorObserver as a silent observer with a clipboard at an airport gate. It doesn't decide who gets on the plane or when the plane leaves. It just notes down every time a passenger (a Route) boards (didPush), deplanes (didPop), or gets transferred to another flight (didReplace). You use these notes to trigger other actions.
HOW IT WORKS: You create a class that extends NavigatorObserver and override methods corresponding to navigation events, such as didPush, didPop, and didReplace. To activate it, you must add an instance of your custom observer to the navigatorObservers list in your MaterialApp or CupertinoApp. When the Navigator acts, it iterates through its registered observers and calls the corresponding method on each one.
WHEN TO USE IT: Use it for cross-cutting concerns related to navigation. Common use cases include: first, analytics, to log which screens a user visits; second, state management, to update a provider or BLoC when the active route changes; third, resource management, like initializing a service when a screen is pushed and closing it when popped. Flutter's own HeroController is an observer that manages hero animations between routes.
WHEN NOT TO USE IT: Do not use NavigatorObserver to control or prevent navigation. It's for observation, not interception. Its methods are void and cannot cancel an event. If you need to conditionally block a user from leaving a screen (e.g., to show an "unsaved changes" dialog), use WillPopScope instead.
ONE CANONICAL EXAMPLE: A simple screen view logger. Create a class AnalyticsObserver extends NavigatorObserver. Override didPush(Route route, Route? previousRoute). In this method, check if route.settings.name is not null and send that name to your analytics service. Finally, add an instance of AnalyticsObserver() to the navigatorObservers list in your MaterialApp. Now, every Navigator.pushNamed call automatically logs a screen view.
Read the original → api.flutter.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.