From react-native-web
Provides navigation patterns for React Native Web using React Navigation, including stack/tab navigators, type-safe params, deep linking, and web URLs. Use for cross-platform routing.
How this skill is triggered — by the user, by Claude, or both
Slash command
/react-native-web:react-native-web-navigationThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Navigation patterns for React Native Web using React Navigation, supporting both native and web platforms with a unified API.
Navigation patterns for React Native Web using React Navigation, supporting both native and web platforms with a unified API.
React Navigation is the standard navigation library for React Native and React Native Web:
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Define navigation types for type safety:
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
type RootStackParamList = {
Home: undefined;
Details: { id: string; title: string };
Profile: { userId: string };
};
type HomeProps = NativeStackScreenProps<RootStackParamList, 'Home'>;
type DetailsProps = NativeStackScreenProps<RootStackParamList, 'Details'>;
function HomeScreen({ navigation }: HomeProps) {
return (
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details', { id: '123', title: 'Item' })}
/>
);
}
React Navigation automatically handles URLs on web:
import { LinkingOptions } from '@react-navigation/native';
const linking: LinkingOptions<RootStackParamList> = {
prefixes: ['https://myapp.com', 'myapp://'],
config: {
screens: {
Home: '',
Details: 'details/:id',
Profile: 'profile/:userId',
},
},
};
<NavigationContainer linking={linking}>
{/* Navigator */}
</NavigationContainer>
✅ Use for screen-to-screen navigation:
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator<RootStackParamList>();
function RootNavigator() {
return (
<Stack.Navigator
screenOptions={{
headerShown: true,
headerStyle: {
backgroundColor: '#007AFF',
},
headerTintColor: '#fff',
}}
>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Home' }}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={({ route }) => ({ title: route.params.title })}
/>
</Stack.Navigator>
);
}
✅ Use for main app sections:
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
const Tab = createBottomTabNavigator<TabParamList>();
function TabNavigator() {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
const iconName = route.name === 'Home' ? 'home' : 'person';
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#007AFF',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}
✅ Use for sidebar navigation on web:
import { createDrawerNavigator } from '@react-navigation/drawer';
import { useWindowDimensions } from 'react-native';
const Drawer = createDrawerNavigator();
function DrawerNavigator() {
const { width } = useWindowDimensions();
const isLargeScreen = width >= 768;
return (
<Drawer.Navigator
screenOptions={{
drawerType: isLargeScreen ? 'permanent' : 'front',
drawerStyle: {
width: 240,
},
}}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Settings" component={SettingsScreen} />
</Drawer.Navigator>
);
}
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
type RootStackParamList = {
Tabs: undefined;
Details: { id: string };
Modal: undefined;
};
type TabParamList = {
Home: undefined;
Search: undefined;
Profile: undefined;
};
const Stack = createNativeStackNavigator<RootStackParamList>();
const Tab = createBottomTabNavigator<TabParamList>();
function TabNavigator() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Search" component={SearchScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}
export function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Tabs"
component={TabNavigator}
options={{ headerShown: false }}
/>
<Stack.Screen name="Details" component={DetailsScreen} />
<Stack.Screen
name="Modal"
component={ModalScreen}
options={{ presentation: 'modal' }}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
import { useNavigation, useRoute } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import type { RouteProp } from '@react-navigation/native';
type DetailsScreenNavigationProp = NativeStackNavigationProp<
RootStackParamList,
'Details'
>;
type DetailsScreenRouteProp = RouteProp<RootStackParamList, 'Details'>;
function DetailsScreen() {
const navigation = useNavigation<DetailsScreenNavigationProp>();
const route = useRoute<DetailsScreenRouteProp>();
const { id, title } = route.params;
return (
<View>
<Text>{title}</Text>
<Button title="Go Back" onPress={() => navigation.goBack()} />
<Button
title="Go to Profile"
onPress={() => navigation.navigate('Profile', { userId: id })}
/>
</View>
);
}
import { LinkingOptions } from '@react-navigation/native';
const linking: LinkingOptions<RootStackParamList> = {
prefixes: ['https://myapp.com', 'myapp://'],
config: {
screens: {
Tabs: {
screens: {
Home: '',
Search: 'search',
Profile: 'profile',
},
},
Details: 'details/:id',
Modal: 'modal',
},
},
};
export function App() {
return (
<NavigationContainer linking={linking} fallback={<LoadingScreen />}>
{/* Navigator */}
</NavigationContainer>
);
}
import { useAuth } from './auth-context';
function RootNavigator() {
const { isAuthenticated } = useAuth();
return (
<Stack.Navigator>
{isAuthenticated ? (
<>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</>
) : (
<>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Register" component={RegisterScreen} />
</>
)}
</Stack.Navigator>
);
}
import { useNavigation } from '@react-navigation/native';
import { useEffect } from 'react';
function ProtectedScreen() {
const navigation = useNavigation();
const { isAuthenticated } = useAuth();
useEffect(() => {
if (!isAuthenticated) {
navigation.navigate('Login');
}
}, [isAuthenticated, navigation]);
if (!isAuthenticated) {
return null;
}
return <View>{/* Protected content */}</View>;
}
import { createNavigationContainerRef } from '@react-navigation/native';
// Create ref outside component
export const navigationRef = createNavigationContainerRef<RootStackParamList>();
// Use in App component
export function App() {
return (
<NavigationContainer ref={navigationRef}>
{/* Navigator */}
</NavigationContainer>
);
}
// Navigate from anywhere
export function navigateToDetails(id: string) {
if (navigationRef.isReady()) {
navigationRef.navigate('Details', { id });
}
}
❌ Don't use React Router directly (use React Navigation):
// Bad - React Router is web-only
import { BrowserRouter, Route } from 'react-router-dom';
// Good - React Navigation works everywhere
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
❌ Don't pass navigation prop manually:
// Bad
<ChildComponent navigation={navigation} />
// Good - use useNavigation hook
function ChildComponent() {
const navigation = useNavigation();
// ...
}
❌ Don't store navigation state in Redux/Context:
// Bad - navigation state should be managed by React Navigation
const [currentScreen, setCurrentScreen] = useState('Home');
// Good - let React Navigation manage state
// Use navigation listeners if you need to react to changes
npx claudepluginhub thebushidocollective/han --plugin react-native-webImplements stack, tab, drawer navigation in React Native apps using React Navigation. Covers installation, setup, deep linking, and navigation patterns.
Provides core concepts, components, platform abstraction, and best practices for React Native Web projects to build cross-platform web and native apps.
Sets up navigation structure for React Native apps: tab bars, stack navigators, drawer menus, deep linking, and type-safe parameters using Expo Router or React Navigation.