From harness-claude
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.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:mobile-navigation-patternThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Implement stack, tab, and drawer navigation in React Native with type-safe routing and deep linking
Implement stack, tab, and drawer navigation in React Native with type-safe routing and deep linking
Expo Router approach (recommended for Expo):
app/
_layout.tsx # Root layout with navigation container
(tabs)/
_layout.tsx # Tab navigator
index.tsx # Home tab
search.tsx # Search tab
profile.tsx # Profile tab
[userId].tsx # Dynamic screen /userId
settings/
_layout.tsx # Stack navigator for settings
index.tsx # Settings main
notifications.tsx # Notification settings
// app/_layout.tsx
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="[userId]" options={{ title: 'Profile' }} />
<Stack.Screen name="settings" options={{ headerShown: false }} />
</Stack>
);
}
// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
import { HomeIcon, SearchIcon, ProfileIcon } from '@/components/icons';
export default function TabLayout() {
return (
<Tabs screenOptions={{ tabBarActiveTintColor: '#007AFF' }}>
<Tabs.Screen
name="index"
options={{
title: 'Home',
tabBarIcon: ({ color, size }) => <HomeIcon color={color} size={size} />,
}}
/>
<Tabs.Screen
name="search"
options={{
title: 'Search',
tabBarIcon: ({ color, size }) => <SearchIcon color={color} size={size} />,
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Profile',
tabBarIcon: ({ color, size }) => <ProfileIcon color={color} size={size} />,
}}
/>
</Tabs>
);
}
import { Link, useRouter } from 'expo-router';
// Declarative — renders an anchor/pressable
<Link href="/settings/notifications">Notification Settings</Link>
<Link href={{ pathname: '/[userId]', params: { userId: '123' } }}>View Profile</Link>
// Imperative — from event handlers
const router = useRouter();
router.push('/settings');
router.replace('/login'); // No back button
router.back();
// types/navigation.ts
export type RootStackParamList = {
Home: undefined;
Profile: { userId: string };
Settings: undefined;
};
export type TabParamList = {
Feed: undefined;
Search: { query?: string };
Account: undefined;
};
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NavigationContainer } from '@react-navigation/native';
const Stack = createNativeStackNavigator<RootStackParamList>();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
// app.config.ts
export default {
scheme: 'myapp',
// Universal links
ios: { associatedDomains: ['applinks:example.com'] },
android: {
intentFilters: [
{
action: 'VIEW',
autoVerify: true,
data: [{ scheme: 'https', host: 'example.com', pathPrefix: '/app' }],
},
],
},
};
// app/_layout.tsx
import { useAuth } from '@/hooks/useAuth';
import { Redirect, Stack } from 'expo-router';
export default function RootLayout() {
const { isAuthenticated, isLoading } = useAuth();
if (isLoading) return <SplashScreen />;
if (!isAuthenticated) return <Redirect href="/login" />;
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
</Stack>
);
}
<Stack.Screen name="create-post" options={{ presentation: 'modal', headerTitle: 'New Post' }} />
Expo Router vs. React Navigation: Expo Router is built on React Navigation and adds file-based routing, automatic deep linking, and typed routes. Use Expo Router for new Expo projects. Use React Navigation directly when you need programmatic navigator composition or are not using Expo.
Navigation patterns by app type:
Performance tips:
lazy: true on tabs to defer rendering until first visitfreezeOnBlur: true to prevent re-renders on inactive screensCommon mistakes:
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeReact Navigation patterns for mobile apps including stack, tab, drawer navigators, deep linking, and typed navigation with TypeScript. Use when building navigation structure, handling deep links, or implementing authentication flows.
Implements stack, tab, drawer navigation in React Native apps using React Navigation. Covers installation, setup, deep linking, and navigation patterns.
Implements file-based routing with Expo Router in Expo apps. Covers app directory structure, Stack/Tab layouts, dynamic routes, deep linking, and programmatic navigation.