D
BLoC PatternHard50 XP4 min read

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

dartNavigation via BlocListener + go_router
Output
// 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.

#navigation#bloc#go-router#route-state