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.
Interview question
Which scenario is NOT an appropriate application for Flutter's NavigatorObserver?
- a.Preventing a user from navigating away from a form with unsaved data.Correct
- b.Tracking user navigation paths for analytics reporting.
- c.Managing the lifecycle of a resource tied to a specific screen's presence.
- d.Synchronizing application state with the currently active route.
Why? this is the answer
NavigatorObserver is designed for observing navigation events, not for intercepting or controlling them. To prevent navigation, such as when a user has unsaved changes, Flutter's WillPopScope widget should be used instead, as NavigatorObserver methods are void and cannot cancel an event.
Just read this? Test yourself on what you have been reading.
Read the original → api.flutter.dev
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on flutter — each one lists the topics its interview covers.
See open roles