Drawer Navigator
Drawer navigation is used for secondary navigation in admin apps, settings-heavy apps, and tablet layouts where a sidebar always makes sense. React Navigation's Drawer works with gesture swipe-to-open by default.
Custom Drawer with Auth-Aware Content
npm install @react-navigation/drawer react-native-gesture-handler react-native-reanimatedDrawer Setup
import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';
import { Ionicons } from '@expo/vector-icons';
const Drawer = createDrawerNavigator();
// Custom drawer content
function CustomDrawerContent(props: DrawerContentComponentProps) {
const user = useAuthUser(); // your auth hook
return (
<DrawerContentScrollView {...props} contentContainerStyle={{ flex: 1, backgroundColor: '#0f172a' }}>
{/* User info at top */}
<View style={{ padding: 20, paddingTop: 48, borderBottomWidth: 1, borderBottomColor: '#1e293b' }}>
<Image source={{ uri: user.avatarUri }} style={{ width: 56, height: 56, borderRadius: 28, marginBottom: 10 }} />
<Text style={{ color: '#f1f5f9', fontWeight: '700', fontSize: 16 }}>{user.name}</Text>
<Text style={{ color: '#64748b', fontSize: 13 }}>{user.email}</Text>
</View>
{/* Standard nav items */}
<DrawerItemList {...props} />
{/* Spacer pushes logout to bottom */}
<View style={{ flex: 1 }} />
{/* Logout at bottom */}
<DrawerItem
label="Sign Out"
icon={({ color }) => <Ionicons name="log-out-outline" size={20} color={color} />}
onPress={signOut}
labelStyle={{ color: '#f87171' }}
style={{ marginBottom: 20 }}
/>
</DrawerContentScrollView>
);
}
function AppDrawer() {
return (
<Drawer.Navigator
drawerContent={props => <CustomDrawerContent {...props} />}
screenOptions={{
drawerStyle: { backgroundColor: '#0f172a', width: 280 },
drawerActiveTintColor: '#6366f1',
drawerInactiveTintColor: '#94a3b8',
drawerActiveBackgroundColor: '#1e293b',
headerShown: false,
}}
>
<Drawer.Screen name="Dashboard" component={DashboardScreen}
options={{ drawerIcon: ({ color }) => <Ionicons name="grid-outline" size={20} color={color} /> }}
/>
<Drawer.Screen name="Analytics" component={AnalyticsScreen}
options={{ drawerIcon: ({ color }) => <Ionicons name="bar-chart-outline" size={20} color={color} /> }}
/>
</Drawer.Navigator>
);
}
// Type stubs
function useAuthUser() { return { name: 'Sarah', email: 'sarah@example.com', avatarUri: 'https://i.pravatar.cc/100' }; }
function signOut() {}
function DashboardScreen() { return null; }
function AnalyticsScreen() { return null; }
type DrawerContentComponentProps = Parameters<Parameters<typeof Drawer.Navigator>[0]['drawerContent'] & {}>[0];Tip
Tip
Practice Drawer Navigator in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
Nest navigators: Stack inside Tabs inside Drawer for complex flows
Practice Task
Note
Practice Task — (1) Write a working example of Drawer Navigator from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with Drawer Navigator is skipping edge case testing — empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready react native code.