ExpoStartup

Drawer Navigation

Drawer Navigation implementation using Expo Router in the Expo Startup template

Drawer Navigation

The Drawer Navigation provides a side menu for additional navigation options, user profile, and settings. It's implemented using Expo Router's Drawer components with a custom drawer content component.

Implementation

The drawer navigation is implemented using two main components:

  1. (drawer)/_layout.tsx - Defines the drawer structure and configuration
  2. CustomDrawerContent.tsx - Custom component for the drawer's content

Basic Usage

Here's a simple example of how to set up drawer navigation with a custom drawer content:

// In (drawer)/_layout.tsx
import { Drawer } from 'expo-router/drawer';
import CustomDrawerContent from '@/components/CustomDrawerContent';
 
export default function DrawerLayout() {
  return (
    <Drawer
      screenOptions={{
        headerShown: false,
        drawerType: 'front',
        drawerStyle: {
          width: '85%',
        },
        swipeEdgeWidth: 80
      }}
      drawerContent={() => <CustomDrawerContent />}
    >
      <Drawer.Screen
        name="index"
        options={{
          title: 'Menu',
        }}
        redirect={true}
      />
      
      {/* Add more screens to the drawer */}
    </Drawer>
  );
}

Creating a Custom Drawer Content

You can create a simple drawer content component like this:

// In CustomDrawerContent.tsx
import { router } from 'expo-router';
import { View, Text, TouchableOpacity } from 'react-native';
import Icon from '@/components/Icon';
 
function NavItem({ href, icon, label }) {
  return (
    <TouchableOpacity 
      onPress={() => router.push(href)}
      className="flex-row items-center py-4"
    >
      <Icon name={icon} size={24} className="mr-4" />
      <Text className="text-lg font-medium">{label}</Text>
    </TouchableOpacity>
  );
}
 
export default function CustomDrawerContent() {
  return (
    <View className="flex-1 p-6 bg-white dark:bg-gray-900">
      {/* User Profile Section */}
      <View className="mb-6 pb-6 border-b border-gray-200 dark:border-gray-700">
        <Text className="text-xl font-bold">John Doe</Text>
        <Text className="text-gray-500">@johndoe</Text>
      </View>
      
      {/* Navigation Links */}
      <NavItem href="/" icon="Home" label="Home" />
      <NavItem href="/profile" icon="User" label="Profile" />
      <NavItem href="/settings" icon="Settings" label="Settings" />
    </View>
  );
}

Features

  • Theme Support - Automatically adapts to light/dark mode
  • User Profile Section - Displays user avatar, name, and stats
  • Navigation Links - Easy navigation to key app sections
  • Animated Transitions - Smooth open/close animations
  • Edge Swiping - Open drawer by swiping from screen edge

Opening the Drawer

The template provides a DrawerButton component and a useDrawer hook to open the drawer from anywhere in your app:

// Using the DrawerButton component
import DrawerButton from '@/components/DrawerButton';
 
function Header() {
  return (
    <View className="flex-row p-4 items-center">
      <DrawerButton />
      <Text className="text-xl font-bold ml-4">App Title</Text>
    </View>
  );
}
 
// Using the useDrawer hook directly
import { useDrawer } from '@/app/contexts/DrawerContext';
 
function CustomButton() {
  const { openDrawer } = useDrawer();
  
  return (
    <Button title="Menu" onPress={openDrawer} />
  );
}

Customization

Changing Drawer Width

<Drawer
  screenOptions={{
    drawerStyle: {
      width: '75%', // Change from default 85%
    },
  }}
>

Adjust Swipe Sensitivity

<Drawer
  screenOptions={{
    swipeEdgeWidth: 50, // Default is 80
  }}
>

Change Drawer Type

<Drawer
  screenOptions={{
    drawerType: 'slide', // Options: 'front', 'back', 'slide', 'permanent'
  }}
>

Best Practices

  1. Group Related Items - Organize drawer items into logical sections
  2. Highlight Active Route - Indicate the currently active route
  3. Limit Item Count - Avoid overwhelming users with too many options
  4. Consistent Icons - Use a cohesive icon set throughout the drawer
  5. Easy Access - Ensure the drawer button is easily accessible from all screens
  6. Responsive Design - Test the drawer on various screen sizes

On this page