This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Stack
Edit page
Learn how to use the Stack navigator in Expo Router.

Navigate between screens, pass params between screens, create dynamic routes, and configure the screen titles and animations.
A stack navigator is the foundational way of navigating between routes in an app. On Android, a stacked route animates on top of the current screen. On iOS, a stacked route animates from the right. Expo Router provides a Stack navigation component that creates a navigation stack and allows you to add new routes in your app.
This guide provides information on how you can create a Stack navigator in your project and customize an individual route's options and header.
Get started
You can use file-based routing to create a stack navigator. Here's an example file structure:
srcapp_layout.tsxindex.tsxdetails.tsxThis file structure produces a layout where the index route is the first route in the stack, and the details route is pushed on top of the index route when navigated.
You can use the src/app/_layout.tsx file to define your app's Stack navigator with these two routes:
Screen options and header configuration
Starting in SDK 55, you can configure screen options and the header using either the options-based API or the new composition components API. Both APIs can be used interchangeably in your project.
Statically configure route options
You can use the <Stack.Screen name={routeName} /> component in the layout component route to statically configure a route's options.
Configure header bar
You can configure the header bar for all routes in a Stack navigator by using the screenOptions prop. This is useful for setting a common header style across all routes.
Set screen options dynamically
To configure a route's options dynamically, you can use either the composition components or the options-based API.
Screen composition API is in alpha and available in SDK 55 and later.
Available header options
The Stack navigator supports comprehensive header configuration options. Below are all the header-related options available:
For additional details and navigator-specific examples, see React Navigation's Native Stack Navigator documentation.
Header buttons
You can add buttons to the header by using the headerLeft and headerRight options or <Stack.Toolbar> component. These options accept a React component that renders in the header.
Configure iOS header toolbar with support for Liquid Glass.
Screen composition API is in alpha and available in SDK 55 and later.
Other screen options
For a complete list of all available other screen options including animations, gestures, and other configurations:
For additional details and navigator-specific examples, see React Navigation's Native Stack Navigator documentation.
Custom push behavior
By default, the Stack navigator removes duplicate screens when pushing a route that is already in the stack. For example, if you push the same screen twice, the second push will be ignored. You can change this push behavior by providing a custom getId() function to the <Stack.Screen>.
For example, the index route in the following layout structure shows a list of different user profiles in the app. Let's make the [details] route a dynamic route so that the app user can navigate to see a profile's details.
srcapp_layout.tsxindex.tsx[details].tsxmatches dynamic paths like '/details1'The Stack navigator will push a new screen every time the app user navigates to a different profile but will fail. If you provide a getId() function that returns a new ID every time, the Stack will push a new screen every time the app user navigates to a profile.
You can use the <Stack.Screen name="[profile]" getId={}> component in the layout component route to modify the push behavior:
Removing stack screens
There are different actions you can use to dismiss and remove one or many routes from a stack.
dismiss action
Dismisses the last screen in the closest stack. If the current screen is the only route in the stack, it will dismiss the entire stack.
You can optionally pass a positive number to dismiss up to that specified number of screens.
Dismiss is different from back as it targets the closest stack and not the current navigator. If you have nested navigators, calling dismiss will take you back multiple screens.
dismissTo action
dismissTowas added in Expo Router4.0.8. It operates similarly to thenavigationfunction in Expo Router v3.
Dismisses screens in the current <Stack /> until the specified Href is reached. If the Href is absent in the history, a push action will be performed instead.
For example, consider the history of /one, /two, /three routes, where /three is the current route. The action router.dismissTo('/one') will cause the history to go back twice, while router.dismissTo('/four') will push the history forward to the /four route.
dismissAll action
To return to the first screen in the closest stack. This is similar to popToTop stack action.
For example, the home route is the first screen, and the settings is the last. To go from settings to home route you'll have to go back to details. However, using the dismissAll action, you can go from settings to home and dismiss any screen in between.
canDismiss action
To check if it is possible to dismiss the current screen. Returns true if the router is within a stack with more than one screen in the stack's history.
iOS 26 Liquid Glass headers
Starting from iOS 26, navigation headers adopt the system's "Liquid Glass" effect by default. It cannot be disabled per screen, so you need to opt out using a global configuration.
Method 1: Use UIDesignRequiresCompatibility
Note: Not supported in Expo Go.This method is a temporary workaround. From iOS 27, this option will be removed by Apple and you cannot opt out of the Liquid Glass effect.
Create a development build and set the UIDesignRequiresCompatibility property to true in app config:
Method 2: Use JavaScript-based navigation stack
Swap the native stack for the JavaScript-driven stack shipped at expo-router/js-stack. This gives you full control over the header UI, at the cost of the performance benefits of the highly optimized iOS navigation views and controllers:
The expo-router/js-stack entry point is the SDK 56 replacement for the @react-navigation/stack library. See the SDK 55 to 56 migration guide for more information.
Common problems
Large title does not collapse when scrolling
When using headerLargeTitle: true (or <Stack.Title large>) with a ScrollView or FlatList, the large title may not collapse on scroll. This happens when the scrollable view is not the direct first child of the screen component.
To fix this, ensure ScrollView or FlatList is the first child rendered by your screen component. If you need a wrapper, set collapsable={false} on it:
If you need to wrap the ScrollView, set collapsable={false} on the wrapper: