ð react-native-web-navigation
Use when implementing navigation in React Native Web projects. Provides patterns for React Navigation, deep linking, and web-specific routing.
Overview
Navigation patterns for React Native Web using React Navigation, supporting both native and web platforms with a unified API.
Key Concepts
React Navigation
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>
);
}
Type-Safe Navigation
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' })}
/>
);
}
Web URLs
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>
Best Practices
Stack Navigator
â 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>
);
}
Tab 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>
);
}
Drawer Navigator (Web)
â 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>
);
}
Examples
Complete Navigation Setup
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>
);
}
Navigation with Hooks
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>
);
}
Deep Linking Configuration
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>
);
}
Common Patterns
Protected Routes
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>
);
}
Navigation Guards
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>;
}
Programmatic Navigation
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 });
}
}
Anti-Patterns
â 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
Related Skills
- react-native-web-core: Core React Native Web concepts
- react-native-web-styling: Styling navigation components
- react-native-web-testing: Testing navigation flows