← スキル一覧に戻る
expo-router
jchaselubitz / drill-app
⭐ 0🍴 0📅 2026年1月18日
SKILL.md
# Expo Router Patterns
## Stack Navigator Configuration
### Root Layout Setup
Use `screenOptions` on the Stack component to set defaults for all screens. Do NOT explicitly list every screen - routes are auto-discovered from the file structure.
```tsx
// app/_layout.tsx
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack screenOptions={{ headerShown: false }} />
);
}
```
### Per-Screen Configuration
Individual screens configure their own options using `<Stack.Screen>` within the component file:
```tsx
// app/lesson/[id].tsx
import { Stack } from 'expo-router';
export default function LessonScreen() {
return (
<View>
<Stack.Screen
options={{
title: 'Lesson',
headerShown: true,
headerBackTitle: 'Back',
}}
/>
{/* Screen content */}
</View>
);
}
```
### Dynamic Header Configuration
Use `useNavigation` with `setOptions` for dynamic header content like buttons:
```tsx
import { useNavigation } from 'expo-router';
import { useLayoutEffect } from 'react';
export default function Screen() {
const navigation = useNavigation();
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<Pressable onPress={handlePress}>
<Ionicons name="add" size={28} />
</Pressable>
),
});
}, [navigation]);
return <View>{/* content */}</View>;
}
```
## Native Tabs (`expo-router/unstable-native-tabs`)
Native tabs provide platform-native tab bar with SF Symbols on iOS:
```tsx
// app/(tabs)/_layout.tsx
import { Icon, Label, NativeTabs } from 'expo-router/unstable-native-tabs';
export default function TabLayout() {
return (
<NativeTabs>
<NativeTabs.Trigger name="index" options={{ title: 'Home' }}>
<Icon sf="house.fill" drawable="custom_android_drawable" />
<Label>Home</Label>
</NativeTabs.Trigger>
</NativeTabs>
);
}
```
## Key Principles
1. **File-based routing**: Routes are auto-discovered from the `app/` directory structure
2. **Minimal configuration**: Only configure what you need to override
3. **Screen-level options**: Screens configure their own headers/options using `<Stack.Screen>` within the component
4. **Layout files**: `_layout.tsx` files define navigation structure for their directory
5. **Route groups**: Parentheses like `(tabs)` create route groups without affecting the URL path
## Common Mistakes to Avoid
- Don't list every screen explicitly in Stack - they're auto-discovered
- Don't use `screenOptions` for route-specific settings - use `<Stack.Screen>` in the route file
- Don't nest navigators deeply - use file-based routing for cleaner structure