Lesson 9

Customizing the Drawer

The default drawer shows a list of screen names. For most apps you'll want to add a user profile header, custom styling, or extra items like a logout button. React Navigation lets you customize everything through options and a custom drawer content component.

Styling the Drawer

Control colors and appearance through screenOptions:

<Drawer.Navigator
  screenOptions={{
    drawerActiveTintColor: '#6200ee',
    drawerInactiveTintColor: '#333',
    drawerActiveBackgroundColor: '#f0e6ff',
    drawerStyle: {
      backgroundColor: '#fff',
      width: 280,
    },
    drawerLabelStyle: {
      fontSize: 16,
    },
  }}
>
  • drawerActiveTintColor / drawerInactiveTintColor — text and icon colors for selected and unselected items
  • drawerActiveBackgroundColor — highlight color behind the active item
  • drawerStyle — styles the drawer panel itself (background, width)
  • drawerLabelStyle — styles the item label text

Custom Drawer Content

For full control, provide a drawerContent function. This replaces the entire drawer panel:

import {
  DrawerContentScrollView,
  DrawerItemList,
  DrawerItem,
} from '@react-navigation/drawer';
import { View, Text, Image, StyleSheet } from 'react-native';

function CustomDrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      <View style={drawerStyles.header}>
        <Image
          source={{ uri: 'https://placekitten.com/80/80' }}
          style={drawerStyles.avatar}
        />
        <Text style={drawerStyles.name}>Jason Brown</Text>
        <Text style={drawerStyles.email}>jason@example.com</Text>
      </View>

      <DrawerItemList {...props} />

      <DrawerItem
        label="Logout"
        onPress={() => alert('Logged out!')}
      />
    </DrawerContentScrollView>
  );
}

const drawerStyles = StyleSheet.create({
  header: { padding: 20, borderBottomWidth: 1, borderBottomColor: '#eee', marginBottom: 8 },
  avatar: { width: 60, height: 60, borderRadius: 30, marginBottom: 8 },
  name: { fontSize: 18, fontWeight: 'bold' },
  email: { fontSize: 14, color: '#666' },
});

Wire it into the navigator:

<Drawer.Navigator drawerContent={(props) => <CustomDrawerContent {...props} />}>
  <Drawer.Screen name="Home" component={HomeScreen} />
  <Drawer.Screen name="Settings" component={SettingsScreen} />
</Drawer.Navigator>

The key pieces:

  • DrawerContentScrollView — provides the scrollable wrapper with proper safe area handling
  • DrawerItemList — renders the default screen items (so you don't have to recreate them)
  • DrawerItem — a standalone item you can add anywhere (like the Logout button)

You can place anything above or below DrawerItemList — a user header, section dividers, footer links, version info. It's just a React component.

Hiding Screens from the Drawer

Sometimes you want a screen in the navigator but not visible in the drawer (for example, a detail screen). Use drawerItemStyle to hide it:

<Drawer.Screen
  name="HiddenScreen"
  component={HiddenScreen}
  options={{ drawerItemStyle: { display: 'none' } }}
/>

Complete Example

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';
import { View, Text, Image, StyleSheet } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

const Drawer = createDrawerNavigator();

function HomeScreen() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Home</Text>
    </View>
  );
}

function SettingsScreen() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Settings</Text>
    </View>
  );
}

function CustomDrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      <View style={drawerStyles.header}>
        <Image
          source={{ uri: 'https://placekitten.com/80/80' }}
          style={drawerStyles.avatar}
        />
        <Text style={drawerStyles.name}>Jason Brown</Text>
        <Text style={drawerStyles.email}>jason@example.com</Text>
      </View>
      <DrawerItemList {...props} />
      <DrawerItem label="Logout" onPress={() => alert('Logged out!')} />
    </DrawerContentScrollView>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
  title: { fontSize: 24 },
});

const drawerStyles = StyleSheet.create({
  header: { padding: 20, borderBottomWidth: 1, borderBottomColor: '#eee', marginBottom: 8 },
  avatar: { width: 60, height: 60, borderRadius: 30, marginBottom: 8 },
  name: { fontSize: 18, fontWeight: 'bold' },
  email: { fontSize: 14, color: '#666' },
});

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator
        drawerContent={(props) => <CustomDrawerContent {...props} />}
        screenOptions={({ route }) => ({
          drawerIcon: ({ color, size }) => {
            const iconName = route.name === 'Home' ? 'home-outline' : 'settings-outline';
            return <Ionicons name={iconName} size={size} color={color} />;
          },
          drawerActiveTintColor: '#6200ee',
        })}
      >
        <Drawer.Screen name="Home" component={HomeScreen} />
        <Drawer.Screen name="Settings" component={SettingsScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

A drawer with a user profile header, icons on each item, and a logout button at the bottom. We've now built with all three navigator types individually — next up: combining them.