Skip to content

Named Routes

In React Router you define a route configuration — an array or JSX tree of <Route path="..." element={...} /> objects — and the router renders the matching component based on the current URL. Flutter has a simpler built-in equivalent: a routes map on MaterialApp that associates string names with builder functions. Calling Navigator.pushNamed(context, '/detail') looks up the name in the map and pushes the matching screen.

Named routes solve the same problem as React Router’s path config: you decouple the navigation call site from the actual screen widget, so you can rename or move screens without updating every push call.

React
// React Router v6 — route config
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const router = createBrowserRouter([
{ path: '/', element: <HomeScreen /> },
{ path: '/detail', element: <DetailScreen /> },
{ path: '/profile', element: <ProfileScreen /> },
]);
// Navigate by path string
navigate('/detail');
navigate('/profile');
Flutter
// Flutter — named routes map
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => const HomeScreen(),
'/detail': (context) => const DetailScreen(),
'/profile': (context) => const ProfileScreen(),
},
);
// Navigate by name
Navigator.pushNamed(context, '/detail');
Navigator.pushNamed(context, '/profile');
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',
      routes: {
        '/':        (context) => const HomeScreen(),
        '/about':   (context) => const AboutScreen(),
        '/contact': (context) => const ContactScreen(),
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/about'),
              child: const Text('About'),
            ),
            const SizedBox(height: 12),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/contact'),
              child: const Text('Contact'),
            ),
          ],
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('About')),
      body: const Center(child: Text('About page')),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Contact')),
      body: const Center(child: Text('Contact page')),
    );
  }
}
Where do you define the named routes map in a Flutter app?
What is the Flutter equivalent of navigate(path, { replace: true }) in React Router?
What is a key limitation of Flutter built-in named routes compared to React Router?
What does initialRoute do in a Flutter MaterialApp?