HomeGuidesReferenceLearn

Drawer

Learn how to use the Drawer layout in Expo Router.


To use drawer navigator you'll need to install some extra dependencies.

Terminal
npx expo install @react-navigation/drawer react-native-gesture-handler react-native-reanimated

Next, you'll need to update your babel.config.js to include the reanimated plugin:

babel.config.js
module.exports = {
  presets: [
      %%placeholder-start%%... %%placeholder-end%%
    ],
    plugins: [
      %%placeholder-start%%... %%placeholder-end%%
      'react-native-reanimated/plugin',
    ],
};

After changing your babel.config.js, run npx expo start --clear once to start the development server and clear the babel cache.

Now you can use the Drawer layout to create a drawer navigator.

app/_layout.js
import { Drawer } from 'expo-router/drawer';

export default function Layout() {
  return <Drawer />;
}

To edit the drawer navigation menu labels, titles and screen options specific screens are required as follows:

app/_layout.js
import { Drawer } from 'expo-router/drawer';

export default function Layout() {
  return (
    <Drawer>
      <Drawer.Screen
        name="index" // This is the name of the page and must match the url from root
        options={{
          drawerLabel: 'Home',
          title: 'overview',
        }}
      />
      <Drawer.Screen
        name="user/[id]" // This is the name of the page and must match the url from root
        options={{
          drawerLabel: 'User',
          title: 'overview',
        }}
      />
    </Drawer>
  );
}

Now you can use the Drawer layout to create a drawer navigator. You'll need to wrap the <Drawer /> in a <GestureHandlerRootView> to enable gestures. It is required as of Expo Router v3 and greater. You only need one <GestureHandlerRootView> in your component tree. Any nested routes are not required to be wrapped individually.

app/_layout.js
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { Drawer } from 'expo-router/drawer';

export default function Layout() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <Drawer />
    </GestureHandlerRootView>
  );
}

To edit the drawer navigation menu labels, titles and screen options specific screens are required as follows:

app/_layout.js
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { Drawer } from 'expo-router/drawer';

export default function Layout() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <Drawer>
        <Drawer.Screen
          name="index" // This is the name of the page and must match the url from root
          options={{
            drawerLabel: 'Home',
            title: 'overview',
          }}
        />
        <Drawer.Screen
          name="user/[id]" // This is the name of the page and must match the url from root
          options={{
            drawerLabel: 'User',
            title: 'overview',
          }}
        />
      </Drawer>
    </GestureHandlerRootView>
  );
}

Note: Be careful when using react-native-gesture-handler on the web. It can increase the JavaScript bundle size significantly. Learn more about using platform-specific modules.