How do you handle navigation from inside a Bloc?
TL;DR: Navigation is a UI concern — Blocs should not call Navigator.push(). Instead, emit a navigation state (e.g., NavigateToHome) and listen in the widget with BlocListener. With go_router, use refreshListenable to auto-redirect based on auth state.
Full Answer
Blocs should never import Navigator or BuildContext. Mixing navigation into business logic makes it impossible to test.
Pattern 1: Navigation State in Bloc
The Bloc emits a state that contains navigation intent (e.g., AuthAuthenticated). BlocListener in the widget layer calls context.go('/home') when it sees this state.
Pattern 2: go_router refreshListenable
go_router's refreshListenable accepts a Listenable. When it notifies, the router re-evaluates its redirect logic. Create a ChangeNotifier that wraps your AuthBloc's stream.
Code Examples
// Pattern 1: Bloc emits -> BlocListener calls context.go() // Pattern 2: Auth state changes -> router re-evaluates redirect
Common Mistakes
- ✗Importing Navigator inside a Bloc — makes Blocs Flutter-dependent and untestable
- ✗Navigating in BlocBuilder instead of BlocListener — builder runs on every rebuild
Interview Tip
Navigation is a side effect — it belongs in BlocListener, not BlocBuilder. Show the go_router refreshListenable pattern for declarative auth-based routing.