React Navigation
CallstackOfficialPublished by Callstack
- Skill
- Tool integration
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured reference for building navigation interfaces in React applications using React Navigation 7. It covers both the modern Static API and the traditional Dynamic API, offering guidance on implementing stacks, tabs, drawers, and sheets. The documentation includes best practices for configuring headers, handling safe areas, and managing navigation state across different platforms.
What it does
- Provides patterns for implementing stack, tab, and drawer navigation.
- Explains how to configure headers and navigation UI elements.
- Offers guidance on handling safe areas and screen insets.
- Demonstrates how to integrate icons and custom backgrounds into navigation components.
- Supports both Static and Dynamic API styles for navigation configuration.
- Includes techniques for programmatic navigation control and scroll-to-top functionality.
When to use it
- When building navigation structures for React-based mobile or web applications.
- When you need to implement consistent UI patterns like sidebars, bottom tabs, or modals.
- When configuring platform-specific navigation behaviors or safe-area insets.
- When migrating or setting up navigation in a React Navigation 7 environment.
Advantages
- Provides clear API selection guidance for new and existing projects.
- Offers standardized patterns for common navigation UI components.
- Includes practical code examples for both Static and Dynamic APIs.
- Addresses cross-platform layout requirements for web and mobile.
Usage examples
- “How do I create a bottom tab navigator in React Navigation 7?”
- The skill provides code snippets for both Static and Dynamic APIs, showing how to use createBottomTabNavigator and configure tab icons.
- “How can I handle safe areas in my navigation header?”
- The skill directs you to the safe-areas reference, explaining how to manage status bar and header insets for a consistent UI.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/callstackincubator/react-navigation/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip react-navigation.zip -d .agents/skills
Documentation by Callstack
React Navigation
Overview
Guide for building navigation UIs with React Navigation.
This skill only applies to React Navigation 7. The API and patterns may not work with different versions.
API Selection
React Navigation offers two API - object-based Static API and component-based Dynamic API.
Existing Apps: Check the current navigation setup and follow the same API style when using the references
New Apps: If the app does not have an existing navigation setup yet, prefer
Static API
When to Apply
Reference this skill when:
Building navigation UI patterns such as stacks, tabs, drawers, sheets etc.
Configuring headers and other built-in navigator UI
Handling safe areas and insets in navigation UI
References
| File | Description |
|---|---|
| stacks.md | Stack based navigation |
| form-sheet.md | Bottom sheet and form sheets |
| bottom-tabs.md | Cross-platform bottom tabs |
| native-bottom-tabs.md | Native bottom tabs |
| material-top-tabs.md | Swipeable Top tabs |
| drawers.md | Drawer navigation and sidebars |
| header.md | Configuring headers |
| safe-areas.md | Safe-area handling |
Problem -> Skill Mapping
| Problem | Start With |
|---|---|
| Showing screens and modals in a stack | stacks.md |
| Showing bottom sheets or form sheets | form-sheet.md |
| Showing screens in bottom tabs or responsive sidebars with web support | bottom-tabs.md |
| Showing screens in native tabs on iOS & Android | native-bottom-tabs.md |
| Showing content in swipeable top tabs | material-top-tabs.md |
| Using a drawer or sidebar | drawers.md |
| Configuring the header in bottom tab or drawer navigator | header.md |
| Handling safe-area such as status bar, header insets, tab bar insets etc. | safe-areas.md |
Files
- ATTRIBUTION.mdAdded by AutoGineer851 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md3.3 KiB
- agents/openai.yaml268 B
- references/bottom-tabs.md12.7 KiB
- references/drawers.md12.0 KiB
- references/form-sheet.md8.0 KiB
- references/header.md6.8 KiB
- references/material-top-tabs.md11.5 KiB
- references/native-bottom-tabs.md8.7 KiB
- references/safe-areas.md3.8 KiB
- references/stacks.md11.7 KiB
references/drawers.md
title: Drawer Navigator impact: HIGH tags: react-navigation, drawer, sidebar, master-detail, header, responsive-layout
Skill: Drawer Navigator
Description
Use createDrawerNavigator for a navigation drawer or sidebar that switches between app sections. If using a drawer for displaying content instead of navigation, use react-native-drawer-layout instead.
When to Use
Building app sections behind a drawer or sidebar
Showing a permanent sidebar on larger screens and a drawer on smaller screens
Using the drawer as the master pane in a master-detail layout
Prerequisites
Install and configure react-native-gesture-handler, react-native-reanimated, and react-native-worklets for drawer navigator to work on native platforms.
Basic Example
Static API
import { createDrawerNavigator } from '@react-navigation/drawer';
const AppDrawer = createDrawerNavigator({
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});Dynamic API
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function AppDrawer() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Profile" component={ProfileScreen} />
</Drawer.Navigator>
);
}Opening and Closing the Drawer
Use navigation.openDrawer(), navigation.closeDrawer(), and navigation.toggleDrawer() inside drawer screens to open or close the drawer programmatically.
import { Button, View } from 'react-native';
import { useNavigation } from '@react-navigation/native';
function HomeScreen() {
const navigation = useNavigation();
return (
<View>
<Button title="Open drawer" onPress={() => navigation.openDrawer()} />
<Button title="Close drawer" onPress={() => navigation.closeDrawer()} />
<Button title="Toggle drawer" onPress={() => navigation.toggleDrawer()} />
</View>
);
}Nesting Drawers
When nesting a drawer inside another drawer, use react-native-drawer-layout for the outer drawer and keep Drawer navigator for the inner navigation drawer.
import * as React from 'react';
import { Text } from 'react-native';
import { Drawer } from 'react-native-drawer-layout';
function App() {
const [rightDrawerOpen, setRightDrawerOpen] = React.useState(false);
return (
<Drawer
open={rightDrawerOpen}
onOpen={() => setRightDrawerOpen(true)}
onClose={() => setRightDrawerOpen(false)}
drawerPosition="right"
renderDrawerContent={() => <Text>Right drawer content</Text>}
>
<AppDrawer />
</Drawer>
);
}Use React context to expose methods for opening or closing the outer drawer from nested screens.
Common Features
Displaying Icons
Use drawerIcon in screenOptions or per-screen options. drawerActiveTintColor and drawerInactiveTintColor control the color passed to the icon and label.
Static API
import Ionicons from '@expo/vector-icons/Ionicons';
import { createDrawerNavigator } from '@react-navigation/drawer';
const AppDrawer = createDrawerNavigator({
screenOptions: ({ route }) => ({
drawerIcon: ({ color, size }) => {
let iconName;
switch (route.name) {
case 'Home':
iconName = 'home-outline';
break;
default:
iconName = 'person-outline';
break;
}
return <Ionicons name={iconName} size={size} color={color} />;
},
drawerActiveTintColor: 'tomato',
drawerInactiveTintColor: 'gray',
}),
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});Dynamic API
import Ionicons from '@expo/vector-icons/Ionicons';
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function AppDrawer() {
return (
<Drawer.Navigator
screenOptions={({ route }) => ({
drawerIcon: ({ color, size }) => {
let iconName;
switch (route.name) {
case 'Home':
iconName = 'home-outline';
break;
default:
iconName = 'person-outline';
break;
}
return <Ionicons name={iconName} size={size} color={color} />;
},
drawerActiveTintColor: 'tomato',
drawerInactiveTintColor: 'gray',
})}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Profile" component={ProfileScreen} />
</Drawer.Navigator>
);
}The drawerIcon option can render any React element. Choose between the icon libraries that best fit the app's design and environment:
@expo/vector-iconsif Expo SDK is configured in the appreact-native-vector-iconsfor an app using React Native Community CLI<Image>for local images
Custom Drawer Content
Use drawerContent to customize the content of drawer, such as adding a header, footer, or custom actions, or replacing with a custom design.
Use DrawerContentScrollView to automatically adjust insets and DrawerItemList to keep default design. Use the navigation prop passed to the custom drawer content instead of useNavigation.
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItem,
DrawerItemList,
} from '@react-navigation/drawer';
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem
label="Help"
onPress={() => props.navigation.navigate('Help')}
/>
</DrawerContentScrollView>
);
}Replace the content with own element if a different design is needed. Use the state prop to access the list of screens and descriptors to access the options for each screen.
Static API
import { createDrawerNavigator } from '@react-navigation/drawer';
const AppDrawer = createDrawerNavigator({
drawerContent: (props) => <CustomDrawerContent {...props} />,
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
Help: HelpScreen,
},
});Dynamic API
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function AppDrawer() {
return (
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Profile" component={ProfileScreen} />
<Drawer.Screen name="Help" component={HelpScreen} />
</Drawer.Navigator>
);
}Types of Drawer
Use drawerType to choose how the drawer behaves.
Choose between front, back, and slide on smaller screens. Use permanent for a sidebar on larger screens. Use useWindowDimensions to conditionally set the type based on screen width for responsive layouts.
Static API
import { useWindowDimensions } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
const AppDrawer = createDrawerNavigator({
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
}).with(({ Navigator }) => {
const { width } = useWindowDimensions();
return (
<Navigator
screenOptions={{
drawerType: width >= 768 ? 'permanent' : 'front',
}}
/>
);
});Dynamic API
import { useWindowDimensions } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function AppDrawer() {
const { width } = useWindowDimensions();
return (
<Drawer.Navigator
screenOptions={{
drawerType: width >= 768 ? 'permanent' : 'front',
}}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Profile" component={ProfileScreen} />
</Drawer.Navigator>
);
}Drawer Position
Use drawerPosition to place the drawer on the left or right side. The default is left in LTR languages and right in RTL languages.
Static API
import { createDrawerNavigator } from '@react-navigation/drawer';
const AppDrawer = createDrawerNavigator({
screenOptions: {
drawerPosition: 'right',
},
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});Dynamic API
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function AppDrawer() {
return (
<Drawer.Navigator
screenOptions={{
drawerPosition: 'right',
}}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Profile" component={ProfileScreen} />
</Drawer.Navigator>
);
}Master Detail Layout
Combine defaultStatus: 'open' with drawerType: 'back' when the drawer should start open and behave like the master pane behind the detail screen.
Static API
import { createDrawerNavigator } from '@react-navigation/drawer';
const AppDrawer = createDrawerNavigator({
defaultStatus: 'open',
screenOptions: {
drawerType: 'back',
drawerStyle: { width: '100%' },
overlayColor: 'transparent',
},
screens: {
Inbox: InboxScreen,
Message: MessageScreen,
},
});Dynamic API
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function AppDrawer() {
return (
<Drawer.Navigator
defaultStatus="open"
screenOptions={{
drawerType: 'back',
drawerStyle: { width: '100%' },
overlayColor: 'transparent',
}}
>
<Drawer.Screen name="Inbox" component={InboxScreen} />
<Drawer.Screen name="Message" component={MessageScreen} />
</Drawer.Navigator>
);
}With defaultStatus: 'open', the drawer's default state is open. So if drawer is closed, the back button will open it.
Customizing Header
Drawer screens show a header by default. Use header.md for common customization patterns.
A custom header can be shown with the header option if a custom design is needed.
Static API
import { getHeaderTitle } from '@react-navigation/elements';
import { createDrawerNavigator } from '@react-navigation/drawer';
const AppDrawer = createDrawerNavigator({
screens: {
Home: {
screen: HomeScreen,
options: {
headerStyle: {
height: 80,
},
header: ({ route, options }) => {
const title = getHeaderTitle(options, route.name);
return <MyHeader title={title} style={options.headerStyle} />;
},
},
},
},
});Dynamic API
import { getHeaderTitle } from '@react-navigation/elements';
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function AppDrawer() {
return (
<Drawer.Navigator>
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{
headerStyle: {
height: 80,
},
header: ({ route, options }) => {
const title = getHeaderTitle(options, route.name);
return <MyHeader title={title} style={options.headerStyle} />;
},
}}
/>
</Drawer.Navigator>
);
}Set
headerShown: falseto hide the header.If a custom header uses a non-default height, set
headerStyle: { height: ... }explicitly to avoid measurement glitches.
Notes
Swipe gestures and gesture-handler customization are not supported on web.
If a drawer is nested under a stack or tab navigator, it renders below that parent navigator's header or tab bar.
Canonical Docs
Related Skills
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Callstack
- Publisher
- Callstack (Official)
- Source
- callstackincubator/agent-skills · skills/react-navigation · commit 59e9d17
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Callstack or Callstack.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download react-navigation.zip