Flutter Drawer: Build a Side Navigation Menu

Coding Liquids blog cover featuring Sagnik Bhattacharya for the Flutter Drawer guide, with a side navigation menu sliding in, a user account header, and ListTile menu items.
Coding Liquids blog cover featuring Sagnik Bhattacharya for the Flutter Drawer guide.

The slide-in side menu — tap the hamburger, navigate, sign out — is a staple of apps with more destinations than a bottom bar can hold. Flutter makes it almost free: hand a Drawer to the Scaffold and it wires up the hamburger icon, the edge swipe, and the open/close animation for you. This guide covers adding the drawer, building a proper header, the menu items, closing the drawer on tap, the right-hand endDrawer, and opening it from a custom button, with paste-ready code.

The Complete Flutter Course thumbnail

The Complete Flutter Course: Build Android, iOS and Web apps

Go from scratch to building industry-standard apps with Riverpod, Firebase, animations, REST APIs, and more.

By Sagnik Bhattacharya and Paulina Knop

Buy now

Every snippet below is paste-ready against current stable Flutter. The drawer is the third navigation pattern, alongside bottom navigation and tabs — reach for it when you have more destinations than fit comfortably elsewhere.

Follow me on Instagram@sagnikteaches

We'll add a drawer, build the header, list the menu items, close the drawer on tap, and cover endDrawer and opening from code.

Connect on LinkedInSagnik Bhattacharya

If you'd rather watch a full app shell with a drawer built and themed, the channel covers these navigation structures end to end.

Subscribe on YouTube@codingliquids

Add a drawer

Pass a Drawer to the Scaffold's drawer property and Flutter adds the hamburger icon and the edge swipe for free. Fill it with a ListView so it scrolls if the menu is long.

Scaffold(
  appBar: AppBar(title: const Text('Coding Liquids')),
  drawer: Drawer(
    child: ListView(
      padding: EdgeInsets.zero,
      children: const [
        DrawerHeader(child: Text('Menu')),
        ListTile(leading: Icon(Icons.home), title: Text('Home')),
        ListTile(leading: Icon(Icons.settings), title: Text('Settings')),
      ],
    ),
  ),
  body: const HomeBody(),
)

Note padding: EdgeInsets.zero on the ListView — without it the header sits below an unwanted top gap, because ListView adds default padding inside the drawer.

A proper header

DrawerHeader gives you a styled top block, but for an account menu, UserAccountsDrawerHeader is purpose-built — it lays out an avatar, a name, and an email in the standard Material arrangement.

UserAccountsDrawerHeader(
  accountName: const Text('Sagnik Bhattacharya'),
  accountEmail: const Text('hello@codingliquids.com'),
  currentAccountPicture: const CircleAvatar(
    child: Text('S'),
  ),
)

This is the quickest way to a polished header. Use plain DrawerHeader with a gradient or logo when the menu isn't account-centric, and UserAccountsDrawerHeader when it is.

The Complete Flutter Course thumbnail

Build a full app navigation shell

The Complete Flutter Course wires drawers, tabs, and bottom bars into real, shipped apps.

By Sagnik Bhattacharya and Paulina Knop

Buy now

Close the drawer on tap

The open drawer is a route on the navigation stack, so a menu item must close it before — or as part of — navigating. Pop the drawer first inside the ListTile's onTap, then push the destination.

ListTile(
  leading: const Icon(Icons.settings),
  title: const Text('Settings'),
  onTap: () {
    Navigator.pop(context); // close the drawer
    Navigator.pushNamed(context, '/settings');
  },
)

Skip the pop and the drawer stays open over the new screen — a classic first-app bug. The pattern is always: close the drawer, then navigate, as covered in the navigation basics.

endDrawer and opening from code

The endDrawer property gives you a second drawer that opens from the right edge — handy for filters or a secondary panel. To open either drawer from your own button, call Scaffold.of(context).openDrawer() (or openEndDrawer()), making sure the context sits below the Scaffold.

Builder(
  builder: (context) => IconButton(
    icon: const Icon(Icons.menu),
    onPressed: () => Scaffold.of(context).openDrawer(),
  ),
)

The Builder matters: a context taken directly in the Scaffold's own build method is above the Scaffold, so Scaffold.of can't find it. Wrapping the button in a Builder — or using a GlobalKey<ScaffoldState> — gives you a context below it.

Common mistakes

  • Forgetting padding: EdgeInsets.zero. The ListView's default padding pushes the header down.
  • Not popping the drawer on tap. It stays open over the destination screen.
  • Scaffold.of with the wrong context. Use a Builder or a GlobalKey so the context is below the Scaffold.
  • A non-scrolling Column for many items. Use a ListView so long menus scroll.
  • Overloading the drawer. For three to five primary destinations, a bottom bar is usually clearer.

Frequently asked questions

How do I add a navigation drawer in Flutter?

Pass a Drawer to the Scaffold's drawer property; Flutter adds the hamburger icon and edge swipe automatically.

How do I close the drawer when a menu item is tapped in Flutter?

Call Navigator.pop(context) in the ListTile's onTap before navigating, since the open drawer is a route on the stack.

What is the difference between drawer and endDrawer in Flutter?

drawer opens from the left as the main menu; endDrawer opens from the right for secondary panels. A Scaffold can have both.

How do I open a Flutter drawer with a custom button?

Call Scaffold.of(context).openDrawer() from a context below the Scaffold — wrap the button in a Builder or use a GlobalKey<ScaffoldState>.

Every Flutter tutorial on this site, more than 120 so far, is free and written by Sagnik Bhattacharya, founder of Coding Liquids. If you want the same ground covered as one guided path, The Complete Flutter Course at codingliquids.com wires drawers, tabs, and bottom bars into real, shipped apps.

Further reads

Keep going with the tutorials that pair with this guide:

Sources: Flutter documentation — Drawer, DrawerHeader, UserAccountsDrawerHeader, Scaffold.drawer and endDrawer, and the "Add a drawer to a screen" cookbook recipe (docs.flutter.dev). Verified against current stable Flutter.