Mastering Navigation in Flutter

Every app needs to navigate between pages, and Flutter does this using the Navigator widget.

How Navigation works?

The fundamental concept of navigation is the “stack”. You can think of it like a stack of cards. The current page you are looking at is the card on the very top. There are two ways you can change which card you are looking at and that is by adding one on top (known as “pushing” it on top), or by removing the top card (“popping” it off the top).

We will walk through a visual example that has three screens in total.

  1. Home Screen
  2. Second Screen
  3. Third Screen

In the diagram below you can see the current state of the app, and what the stack looks like at that state.

3 screens, with the current stack to the right


Like in the card example let’s say we want our app to navigate to a different screen called “Second Screen”. We would want to push it onto the top of the stack of pages.

arrow showing that the second screen will be pushed on top

Once this is executed, the current application and stack will look like this.

Second screen is visible, with the current stack being 2 pages deep

If we follow the same process and navigate to a third screen our application and stack will look like this.

Third screen is visible, with the current stack being 3 pages deep


To go back and see the previous “Second Screen” you would need to “pop” the topmost layer off of the current stack.

arrow showing that the third screen will be removed

This will result in the stack being 2 pages deep, and you can see the “Second Screen” again.

Second screen is visible, with the current stack being 2 pages deep

Basic Navigation


That is the main concept of navigation within an application. To use it within your Flutter app, your code will look like this:

    MaterialPageRoute(builder: (context) => const SecondPage())

You will use the Navigator widget of the current context, and call the push method. This will add a new layer to the stack.

That navigation “stack” that we were talking about is actually a stack of Route objects. These routes are the actual pathways to get to the specific screen. A Route can have some extra behaviors and properties. For example, you can define what type of animation will be used when bringing in the new page.


In the code above we use a MaterialPageRoute which is a platform-specific Route. What does that mean?

It will check what platform you are running (e.g. iOS, Android), and perform the platform-specific animations for transitioning between pages.

For Android, it zooms and fades, while for iOS it slides in from the right side.


To go back to the previous screen, the code will look like this:


Named Navigation

If you’re coming from web development, you will probably be familiar with routes. In the URL of the website, you can see the route for the different pages. For example, this page is on the /navigation route within the /flutter route.

You can assign these names within Flutter and maneuver throughout your application using them.


Flutter actually doesn’t recommend you to use named routes because the behavior of deep links can’t be customized, and the forward button doesn’t work. For a solution with all this, you should use Navigator 2.0

When using named navigation, instead of defining the route on the fly, you do it ahead of time. These routes need to be configured within the MaterialApp

  initialRoute: '/',
  routes: {
    '/': (context) => const HomeScreen(),
    '/second': (context) => const SecondScreen(),

The initial route on any website or app is '/'. You can customize this in Flutter to something else, but we will keep it '/'.

Within the routes, we define all our routes. So the '/' route will lead us to our Home Screen, where our app will start, and we will predefine a '/second' route which we will be able to use to navigate to the second screen.

Where is Hungrimind home route?

Depending when you read this, you might notice always redirects to /flutter. Eventually there will be a home page on the '/' route, but for now everything gets directed to /flutter.


Using named routes allows your syntax to be a little cleaner since your routes were already defined.



The logic is the same for popping as before, since don’t have to define the specific route. We just remove the very top layer.

For any content improvements or requests please leave a GitHub issue.