← All courses

Navigation & Routing

🗓 May 31, 2026 ⏱ 2 min read

How Flutter navigation works

Flutter manages screens as a stack: you push a new screen on top to go forward, and pop it to go back. The Navigator handles this stack, the transition animations, and the back button.

Pushing and popping

// go to a new screen
Navigator.push(
  context,
  MaterialPageRoute(builder: (_) => const ProfilePage()),
);

// go back
Navigator.pop(context);

Passing data forward

Pass data by giving it to the destination widget’s constructor:

Navigator.push(
  context,
  MaterialPageRoute(builder: (_) => ProfilePage(userId: 42)),
);

class ProfilePage extends StatelessWidget {
  final int userId;
  const ProfilePage({required this.userId, super.key});
  // ...
}

Getting data back

push returns a Future that completes when the screen pops — perfect for “pick something and return it”:

final selected = await Navigator.push<String>(
  context,
  MaterialPageRoute(builder: (_) => const PickerPage()),
);
// in PickerPage: Navigator.pop(context, 'Apple');

Named routes

For larger apps, register routes by name to avoid building MaterialPageRoute everywhere:

MaterialApp(
  routes: {
    '/': (_) => const HomePage(),
    '/settings': (_) => const SettingsPage(),
  },
);

Navigator.pushNamed(context, '/settings');

go_router for modern, scalable navigation

For bigger apps, deep links and web support, the go_router package (officially recommended) gives clean, URL-based routing.

final router = GoRouter(routes: [
  GoRoute(path: '/', builder: (_, __) => const HomePage()),
  GoRoute(path: '/user/:id', builder: (_, s) => UserPage(id: s.pathParameters['id']!)),
]);
context.go('/user/42');

Bottom navigation

For tabbed apps, combine a Scaffold with a BottomNavigationBar (or NavigationBar in Material 3) and switch the body based on the selected index.

Common mistakes

  • Forgetting to await the result of push when you need a return value.
  • Passing huge objects between screens instead of an id.
  • Building a complex app on raw Navigator when go_router would be cleaner.
Summary: Flutter navigates with a stack — push to go forward, pop to go back. Pass data via constructors, get results from the returned Future, use named routes for structure, and adopt go_router for larger, URL-driven apps.