1--- 2title: Stack 3description: Learn how to use the Stack Layout in Expo Router. 4--- 5 6import { FileTree } from '~/ui/components/FileTree'; 7import { BoxLink } from '~/ui/components/BoxLink'; 8import { BookOpen02Icon } from '@expo/styleguide-icons'; 9 10The `Stack` Layout in Expo Router wraps the [Native Stack Navigator](https://reactnavigation.org/docs/native-stack-navigator) from React Navigation, not to be confused with the legacy [JS Stack Navigator](https://reactnavigation.org/docs/stack-navigator). 11 12<FileTree files={['app/_layout.js', 'app/index.js', 'app/detail.js']} /> 13 14To create a `Stack` layout with two screens as shown in the file structure above: 15 16```js app/_layout.js 17import { Stack } from 'expo-router/stack'; 18 19export default function Layout() { 20 return <Stack />; 21} 22``` 23 24## Configure header bar 25 26Use the `screenOptions` prop to configure the header bar. 27 28```jsx app/_layout.js 29import { Stack } from 'expo-router'; 30 31export default function Layout() { 32 return ( 33 <Stack 34 screenOptions={{ 35 headerStyle: { 36 backgroundColor: '#f4511e', 37 }, 38 headerTintColor: '#fff', 39 headerTitleStyle: { 40 fontWeight: 'bold', 41 }, 42 }} 43 /> 44 ); 45} 46``` 47 48You can use a layout's Screen component to configure the header bar dynamically from within the route. This is good for interactions that change the UI. 49 50```jsx app/home.js 51import { Link, Stack } from 'expo-router'; 52import { Image, Text, View } from 'react-native'; 53 54function LogoTitle() { 55 return ( 56 <Image 57 style={{ width: 50, height: 50 }} 58 source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }} 59 /> 60 ); 61} 62 63export default function Home() { 64 return ( 65 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> 66 <Stack.Screen 67 options={{ 68 // https://reactnavigation.org/docs/headers#setting-the-header-title 69 title: 'My home', 70 // https://reactnavigation.org/docs/headers#adjusting-header-styles 71 headerStyle: { backgroundColor: '#f4511e' }, 72 headerTintColor: '#fff', 73 headerTitleStyle: { 74 fontWeight: 'bold', 75 }, 76 // https://reactnavigation.org/docs/headers#replacing-the-title-with-a-custom-component 77 headerTitle: props => <LogoTitle {...props} />, 78 }} 79 /> 80 <Text>Home Screen</Text> 81 <Link href={{ pathname: 'details', params: { name: 'Bacon' } }}>Go to Details</Link> 82 </View> 83 ); 84} 85``` 86 87You can use the imperative API `router.setParams()` function to configure the route dynamically. 88 89```jsx app/details.js 90import { View, Text } from 'react-native'; 91import { Stack, useLocalSearchParams, useRouter } from 'expo-router'; 92 93export default function Details() { 94 const router = useRouter(); 95 const params = useLocalSearchParams(); 96 97 return ( 98 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> 99 <Stack.Screen 100 options={{ 101 title: params.name, 102 }} 103 /> 104 <Text 105 onPress={() => { 106 router.setParams({ name: 'Updated' }); 107 }}> 108 Update the title 109 </Text> 110 </View> 111 ); 112} 113``` 114 115## Header buttons 116 117With the following file structure: 118 119<FileTree files={['app/_layout.js', 'app/home.js']} /> 120 121You can use the `<Stack.Screen name={routeName} />` component in the layout component route to statically configure screen options. This is useful for tab bars or drawers which need to have an icon defined ahead of time. 122 123```jsx app/_layout.js 124import { Stack } from 'expo-router'; 125 126export default function Layout() { 127 return ( 128 <Stack 129 // https://reactnavigation.org/docs/headers#sharing-common-options-across-screens 130 /* @info */ 131 screenOptions={{ 132 headerStyle: { 133 backgroundColor: '#f4511e', 134 }, 135 headerTintColor: '#fff', 136 headerTitleStyle: { 137 fontWeight: 'bold', 138 }, 139 }}> 140 /* @end */ 141 {/* Optionally configure static options outside the route. */} 142 /* @info */ 143 <Stack.Screen name="home" options={{}} /> 144 /* @end */ 145 </Stack> 146 ); 147} 148``` 149 150Use the `<Stack.Screen />` component in the child route to dynamically configure options. 151 152```jsx app/home.js 153import { Button, Text, Image } from 'react-native'; 154/* @info */ 155import { Stack } from 'expo-router'; 156/* @end */ 157 158function LogoTitle() { 159 return ( 160 <Image 161 style={{ width: 50, height: 50 }} 162 source={require('@expo/snack-static/react-native-logo.png')} 163 /> 164 ); 165} 166 167export default function Home() { 168 const [count, setCount] = React.useState(0); 169 170 return ( 171 <> 172 /* @info */ 173 <Stack.Screen 174 options={{ 175 headerTitle: props => <LogoTitle {...props} />, 176 headerRight: () => <Button onPress={() => setCount(c => c + 1)} title="Update count" />, 177 }} 178 /> 179 /* @end */ 180 <Text>Count: {count}</Text> 181 </> 182 ); 183} 184``` 185 186## Custom push behavior 187 188By default, the `Stack` will deduplicate pages when pushing a route that is already in the stack. For example, if you push the same profile twice, the second push will be ignored. You can change the pushing behavior by providing a custom `getId` function to the `Stack.Screen`. 189 190<FileTree files={['app/_layout.js', 'app/[user].js']} /> 191 192You can use the `<Stack.Screen name="[user]" getId={} />` component in the layout component route to modify the pushing behavior. In the following example, the `getId` function pushes a new page every time the user navigates to a profile. 193 194```jsx app/_layout.js 195import { Stack } from 'expo-router'; 196 197export default function Layout() { 198 return ( 199 <Stack> 200 <Stack.Screen 201 name="[user]" 202 /* @info Returning a new ID everytime will cause every page to push. */ 203 getId={({ params }) => String(Date.now())} 204 /* @end */ 205 /> 206 </Stack> 207 ); 208} 209``` 210 211## Next steps 212 213<BoxLink 214 title="Native Stack Navigator: Options" 215 Icon={BookOpen02Icon} 216 description="For a list of all options, see React Navigation's documentation." 217 href="https://reactnavigation.org/docs/native-stack-navigator#options" 218/> 219 220<BoxLink 221 title="Tabs layout" 222 Icon={BookOpen02Icon} 223 description="Learn how to use Tabs layout in Expo Router." 224 href="/router/advanced/tabs" 225/> 226