on the Stack component to set defaults for all screens. Do NOT explicitly list every screen - routes are auto-discovered from the file structure.
// 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
within the component file:
// 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:
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:
// 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
File-based routing
Routes are auto-discovered from the
app/
directory structure
Minimal configuration
Only configure what you need to override
Screen-level options
Screens configure their own headers/options using
within the component
Layout files
:
_layout.tsx
files define navigation structure for their directory
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
in the route file
Don't nest navigators deeply - use file-based routing for cleaner structure