Skip to content

Navigation

In React, navigation is typically URL-driven: react-router maps URL paths to components, the browser history API records each visit, and the user can deep-link to any screen by typing an address. Flutter takes a different approach. By default, Flutter uses an imperative stack managed by a Navigator widget — you push routes onto the stack and pop them off, much like calling history.push and history.back in plain JavaScript, but without any URL involvement on mobile.

Both models converge for web and deep-linking scenarios. Flutter’s go_router package (covered in its own lesson) brings declarative, URL-based routing that maps almost directly onto react-router v6.

LessonFlutter conceptReact analogy
Navigator basicsNavigator.push / .popuseNavigate, history.push
Named routesroutes: map + pushNamed<Routes> + <Route path="...">
go_routerGoRouter, GoRoutereact-router v6 createBrowserRouter
Passing dataConstructor args, await popRoute state, useParams, callbacks
Tabs & drawerBottomNavigationBar, DrawerTab libs, sidebar components

The demo below shows the core Flutter navigation primitive: Navigator.push takes a BuildContext and a Route object, pushes the new screen onto the stack, and Flutter automatically wires up the back button. Navigator.pop returns to the previous screen.

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => const DetailScreen()),
            );
          },
          child: const Text('Go to Detail'),
        ),
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  const DetailScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Detail')),
      body: Center(
        child: ElevatedButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('Go Back'),
        ),
      ),
    );
  }
}
What is the primary mental model Flutter uses for default navigation?
Which Flutter widget manages the navigation stack?
Which Flutter package brings react-router v6-style declarative, URL-based routing to Flutter?
In the push/pop model, what happens to the previous screen when you call Navigator.push?