This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 55).
Expo Router
A file-based routing library for React Native and web applications.
expo-router is a routing library for React Native and web apps. It enables navigation management using a file-based routing system and provides native navigation components and is built on top of React Navigation.
Learn about Expo Router basics, navigation patterns, core concepts, and more.
Installation
To use Expo Router in your project, you need to install. Follow the instructions from the Expo Router's installation guide:
Learn how to install Expo Router in your project.
Configuration in app config
If you are using the default template to create a new project, expo-router's config plugin is already configured in your app config.
Example app.json with config plugin
{ "expo": { "plugins": ["expo-router"] } }
Configurable properties
| Name | Default | Description |
|---|---|---|
root | "app" | Changes the routes directory from |
origin | undefined | Production origin URL where assets in the public folder are hosted. The fetch function is polyfilled to support relative requests from this origin in production. The development origin is inferred using the Expo CLI development server. |
headOrigin | undefined | A more specific origin URL used in the |
asyncRoutes | undefined | Enable async routes (lazy loading). Can be a boolean, a string ( |
platformRoutes | true | Enable or disable platform-specific routes (for example, index.android.tsx and index.ios.tsx). |
sitemap | true | Enable or disable the automatically generated sitemap at /_sitemap. |
partialRouteTypes | true | Enable partial typed routes generation. This allows TypeScript to provide type checking for routes without requiring all routes to be statically known. |
redirects | undefined | An array of static redirect rules. Each rule should have |
rewrites | undefined | An array of static rewrite rules. Each rule should have |
headers | undefined | A list of headers that are set on every route response from the server. The value can be a string or an array of strings. |
disableSynchronousScreensUpdates | false | Disable synchronous layout updates for native screens. This can help with performance in some cases. |
unstable_useServerMiddleware | false | Experimental Enable server middleware support with a |
unstable_useServerDataLoaders | false | Experimental Enable data loader support. This is only supported for |
unstable_useServerRendering | false | Experimental Enable server-side rendering. When enabled with |
Usage
For information core concepts, notation patterns, navigation layouts, and common navigation patterns, start with Router 101 section:
APIs
| API | Description |
|---|---|
| Stack | Stack navigator, toolbar, and screen components |
| Link | Link and Redirect components |
| Color | Platform color utilities |
| Native Tabs | Native tab navigation |
| Split View | Split view layout |
| UI | Headless tab components |
API
import { useRouter, Tabs, Navigator, Slot } from 'expo-router';
Components
Type: React.Element<BadgeProps>
Type: React.Element<ErrorBoundaryProps>
Type: React.Element<LabelProps>
Type: React.Element<Omit<NavigatorProps<any>, 'children'>>
Renders the currently selected content.
There are actually two different implementations of <Slot/>:
- Used inside a
_layoutas theNavigator - Used inside a
Navigatoras the content
Since a custom Navigator will set the NavigatorContext.contextKey to
the current _layout, you can use this to determine if you are inside
a custom navigator or not.
Type: React.Element<VectorIconProps<NameT>>
Helper component for loading vector icons.
Prefer using the md and sf props on Icon rather than using this component directly.
Only use this component when you need to load a specific icon from a vector icon family.
Example
import { Icon, VectorIcon } from 'expo-router'; import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons'; <Icon src={<VectorIcon family={MaterialCommunityIcons} name="home" />} />
{
getImageSource: (name: NameT, size: number, color: ColorValue) => Promise<ImageSourcePropType | null>
}The family of the vector icon.
Example
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
Type: React.Element<ScreenProps<TabsProps, TabNavigationState<ParamListBase>, BottomTabNavigationEventMap>>
Constants
Type: Theme
Type: Theme
Type: {
addListener: (eventType: EventType, callback: (event: Payload<EventType>) => void) => () => void,
emit: (type: EventType, event: Payload<EventType>) => void,
enable: () => void,
isEnabled: () => boolean,
saveCurrentPathname: () => void,
}
Hooks
| Parameter | Type | Description |
|---|---|---|
| effect | EffectCallback | Memoized callback containing the effect, should optionally return a cleanup function. |
| do_not_pass_a_second_prop(optional) | undefined | - |
Hook to run an effect whenever a route is focused. Similar to
React.useEffect.
This can be used to perform side-effects such as fetching data or subscribing to events.
The passed callback should be wrapped in React.useCallback
to avoid running the effect too often.
voidExample
import { useFocusEffect } from 'expo-router'; import { useCallback } from 'react'; export default function Route() { useFocusEffect( // Callback should be wrapped in `React.useCallback` to avoid running the effect too often. useCallback(() => { // Invoked whenever the route is focused. console.log("Hello, I'm focused!"); // Return function is invoked whenever the route gets out of focus. return () => { console.log('This route is now unfocused.'); }; }, []), ); return </>; }
Returns URL parameters for globally selected route, including dynamic path segments. This function updates even when the route is not focused. Useful for analytics or other background operations that don't draw to the screen.
Route URL example: acme://profile/baconbrix?extra=info.
When querying search params in a stack, opt-towards using
useLocalSearchParams because it will only update when the route is focused.
Note: For usage information, see Local versus global search parameters.
RouteParams<TRoute> & TParamsExample
import { Text } from 'react-native'; import { useGlobalSearchParams } from 'expo-router'; export default function Route() { // user=baconbrix & extra=info const { user, extra } = useGlobalSearchParams(); return <Text>User: {user}</Text>; }
Hook to get the current focus state of the screen. Returns a true if screen is focused, otherwise false.
This can be used if a component needs to render something based on the focus state.
booleanReturns the result of the loader function for the calling route.
LoaderFunctionResult<T>Example
import { Text } from 'react-native'; import { useLoaderData } from 'expo-router'; export function loader() { return Promise.resolve({ foo: 'bar' }}; } export default function Route() { const data = useLoaderData<typeof loader>(); // { foo: 'bar' } return <Text>Data: {JSON.stringify(data)}</Text>; }
Returns the URL parameters for the contextually focused route. Useful for stacks where you may push a new screen that changes the query parameters. For dynamic routes, both the route parameters and the search parameters are returned.
Route URL example: acme://profile/baconbrix?extra=info.
To observe updates even when the invoking route is not focused, use useGlobalSearchParams.
Note: For usage information, see Local versus global search parameters.
RouteParams<TRoute> & TParamsExample
import { Text } from 'react-native'; import { useLocalSearchParams } from 'expo-router'; export default function Route() { // user=baconbrix & extra=info const { user, extra } = useLocalSearchParams(); return <Text>User: {user}</Text>; }
| Parameter | Type | Description |
|---|---|---|
| parent(optional) | string | HrefObject | Provide an absolute path such as |
Returns the underlying React Navigation navigation object
to imperatively access layout-specific functionality like navigation.openDrawer() in a
Drawer layout.
TThe navigation object for the current route.
See: React Navigation documentation on navigation dependent functions for more information.
Example
import { useNavigation } from 'expo-router'; export default function Route() { // Access the current navigation object for the current route. const navigation = useNavigation(); return ( <View> <Text onPress={() => { // Open the drawer view. navigation.openDrawer(); }}> Open Drawer </Text> </View> ); }
When using nested layouts, you can access higher-order layouts by passing a secondary argument denoting the layout route.
For example, /menu/_layout.tsx is nested inside /app/orders/, you can use useNavigation('/orders/menu/').
Example
import { useNavigation } from 'expo-router'; export default function MenuRoute() { const rootLayout = useNavigation('/'); const ordersLayout = useNavigation('/orders'); // Same as the default results of `useNavigation()` when invoked in this route. const parentLayout = useNavigation('/orders/menu'); }
If you attempt to access a layout that doesn't exist, an error such as
Could not find parent navigation with route "/non-existent" is thrown.
| Parameter | Type | Description |
|---|---|---|
| createRouter | RouterFactory<State, Readonly<{
payload: object,
source: string,
target: string,
type: string
}>, RouterOptions> | Factory method which returns router object. |
| options | DefaultNavigatorOptions<ParamListBase, string | undefined, State, ScreenOptions, EventMap, any> & RouterOptions | Options object containing |
Hook for building navigators.
{
describe: (route: RouteProp<ParamListBase>, placeholder: boolean) => Descriptor<ScreenOptions, Omit<NavigationHelpersCommon<ParamListBase, State>, 'getParent'> & {
} & NavigationHelpersRoute<ParamListBase, string> & EventConsumer<EventMap & EventMapCore<State>> & PrivateValueStore<[ParamListBase, string, EventMap]> & ActionHelpers, RouteProp<ParamListBase>>,
descriptors: Record<string, Descriptor<ScreenOptions, Omit<NavigationHelpersCommon<ParamListBase, State>, 'getParent'> & {
} & NavigationHelpersRoute<ParamListBase, string> & EventConsumer<EventMap & EventMapCore<State>> & PrivateValueStore<[ParamListBase, string, EventMap]> & ActionHelpers, RouteProp<ParamListBase>>>,
navigation: {
} & PrivateValueStore<[ParamListBase, unknown, unknown]> & EventEmitter<EventMap> & NavigationHelpersRoute<ParamListBase, string> & ActionHelpers,
NavigationContent: (__namedParameters: {
children: ReactNode
}) => Element,
state: State
}An object containing state, navigation, descriptors objects.
NavigationContainerRefWithCurrent<RootParamList>The root <NavigationContainer /> ref for the app. The ref.current may be null
if the <NavigationContainer /> hasn't mounted yet.
| Parameter | Type | Description |
|---|---|---|
| selector | Selector<ParamList, T> | Selector function to get a value from the state. |
Hook to get a value from the current navigation state using a selector.
TReturns the currently selected route location without search parameters. For example, /acme?foo=bar returns /acme.
Segments will be normalized. For example, /[id]?id=normal becomes /normal.
stringExample
import { Text } from 'react-native'; import { usePathname } from 'expo-router'; export default function Route() { // pathname = "/profile/baconbrix" const pathname = usePathname(); return <Text>Pathname: {pathname}</Text>; }
| Parameter | Type | Description |
|---|---|---|
| preventRemove | boolean | Boolean indicating whether to prevent screen from being removed. |
| callback | (options: {
data: {
action: NavigationAction
}
}) => void | Function which is executed when screen was prevented from being removed. |
Hook to prevent screen from being removed. Can be used to prevent users from leaving the screen.
voidDeprecated: Use
useNavigationContainerRefinstead, which returns a Reactref.
NavigationContainerRef<RootParamList> | nullReturns the navigation state of the navigator which contains the current screen.
NavigationStateExample
import { useRootNavigationState } from 'expo-router'; export default function Route() { const { routes } = useRootNavigationState(); return <Text>{routes[0].name}</Text>; }
Hook to access the route prop of the parent screen anywhere.
TRoute prop of the parent screen.
Returns a list of selected file segments for the currently selected route. Segments are not normalized,
so they will be the same as the file path. For example, /[id]?id=normal becomes ["[id]"].
RouteSegments<TSegments>Example
import { Text } from 'react-native'; import { useSegments } from 'expo-router'; export default function Route() { // segments = ["profile", "[user]"] const segments = useSegments(); return <Text>Hello</Text>; }
useSegments can be typed using an abstract. Consider the following file structure:
- app - [user] - index.tsx - followers.tsx - settings.tsx
This can be strictly typed using the following abstract with useSegments hook:
const [first, second] = useSegments<['settings'] | ['[user]'] | ['[user]', 'followers']>()
SitemapType | nullThemeClasses
Methods
Deprecated: This function may be replaced in the future version of expo-router.
| Parameter | Type | Description |
|---|---|---|
| Navigator | ComponentType<any> | The navigator component. Should be wrapped with |
Higher order component to create a Navigator and Screen pair.
Custom navigators should wrap the navigator component in createNavigator before exporting.
(config: any) => anyFactory method to create a Navigator and Screen pair.
Element| Parameter | Type |
|---|---|
| args | TabRouterOptions |
TabRouter is considered an internal implementation and its behavior may change without a notice between expo-router's version
Router<TabNavigationState<ParamListBase>, Action | TabActionType>| Parameter | Type | Description |
|---|---|---|
| Nav | T | The navigator component to wrap. |
| processor(optional) | (options: ScreenProps[]) => ScreenProps[] | A function that processes the screens before passing them to the navigator. |
| useOnlyUserDefinedScreens(optional) | boolean | If true, all screens not specified as navigator's children will be ignored. Default: false |
Returns a navigator that automatically injects matched routes and renders nothing when there are no children.
Return type with children prop optional.
Enables use of other built-in React Navigation navigators and other navigators built with the React Navigation custom navigator API.
Component<PropsWithoutRef<PickPartial<ComponentProps<T>, 'children'>>> & {
Protected: FunctionComponent<ProtectedProps>,
Screen: (props: ScreenProps<TOptions, TState, TEventMap>) => null
}Example
import { ParamListBase, TabNavigationState } from "@react-navigation/native"; import { createMaterialTopTabNavigator, MaterialTopTabNavigationOptions, MaterialTopTabNavigationEventMap, } from "@react-navigation/material-top-tabs"; import { withLayoutContext } from "expo-router"; const MaterialTopTabs = createMaterialTopTabNavigator(); const ExpoRouterMaterialTopTabs = withLayoutContext< MaterialTopTabNavigationOptions, typeof MaterialTopTabs.Navigator, TabNavigationState<ParamListBase>, MaterialTopTabNavigationEventMap >(MaterialTopTabs.Navigator); export default function TabLayout() { return <ExpoRouterMaterialTopTabs />; }
Types
Literal Type: union
Acceptable values are: Omit<A & B, keyof NavigationProp<any>> | NavigationProp<undefined & undefined, undefined, undefined | undefined, undefined, undefined, undefined>
Type: DefaultRouterOptions<Keyof<ParamList>> extended by:
| Property | Type | Description |
|---|---|---|
| children | React.ReactNode | Children React Elements to extract the route configuration from.
Only |
| layout(optional) | (props: {
children: React.ReactNode,
descriptors: Record<string, Descriptor<ScreenOptions, NavigationProp<ParamList, keyof ParamList, string | undefined, State, ScreenOptions, EventMap>, RouteProp<ParamList>>>,
navigation: NavigationHelpers<ParamList>,
state: State
}) => React.ReactElement | Layout for the navigator. Useful for wrapping with a component with access to navigator's state and options. |
| screenLayout(optional) | (props: ScreenLayoutArgs<ParamList, keyof ParamList, ScreenOptions, Navigation>) => React.ReactElement | Layout for all screens under this navigator. |
| screenListeners(optional) | ScreenListeners<State, EventMap> | (props: {
navigation: Navigation,
route: RouteProp<ParamList>
}) => ScreenListeners<State, EventMap> | Event listeners for all the screens in the navigator. |
| screenOptions(optional) | ScreenOptions | (props: {
navigation: Navigation,
route: RouteProp<ParamList>,
theme: ReactNavigation.Theme
}) => ScreenOptions | Default options for all screens under this navigator. |
| UNSTABLE_routeNamesChangeBehavior(optional) | 'firstMatch' | 'lastUnhandled' | What should happen when the available route names change. e.g. when different screens are rendered based on a condition.
Example cases where previous state might have been unhandled:
In these cases, 'lastUnhandled' will reuse the unhandled state if present. If there's no unhandled state, it will fallback to 'firstMatch' behavior. Caveats:
|
| UNSTABLE_router(optional) | (original: Router<State, Action>) => Partial<Router<State, Action>> | A function returning overrides for the underlying router used by the navigator. The overrides will be shallow merged onto the original router. It receives the original router as an argument to the function. This must be a pure function and cannot reference outside dynamic variables. |
| Property | Type | Description |
|---|---|---|
| navigation | Navigation | Navigation object for the screen |
| options | ScreenOptions | Options for the route. |
| route | Route | Route object for the screen |
| render | () => Element | Render the component associated with this route. |
| Property | Type | Description |
|---|---|---|
| enabled(optional) | boolean | - |
| formatter(optional) | (options: Record<string, any> | undefined, route: Route<string> | undefined) => string | - |
Memoized callback containing the effect, should optionally return a cleanup function.
undefined | void | () => void
Type: extended by:
| Property | Type | Description |
|---|---|---|
| target(optional) | string | - |
| type | EventName | Type of the event (e.g. |
| Property | Type | Description |
|---|---|---|
| emit | (options: {
target: string,
type: EventName
} & undefined & undefined) => EventArg<EventName, [canPreventDefault], [data]> | Emit an event to child screens. |
| Parameter | Type |
|---|---|
| e | EventArg<EventName, undefined, [data]> |
void
| Property | Type | Description |
|---|---|---|
| beforeRemove | {
canPreventDefault: true,
data: {
action: NavigationAction
}
} | - |
| blur | {
data: undefined
} | - |
| focus | {
data: undefined
} | - |
| state | {
data: {
state: State
}
} | - |
Literal Type: union
Acceptable values are: {string}:{string} | //{string}
The main routing type for Expo Router. It includes all available routes with strongly typed parameters. It can either be:
- string: A full path like
/profile/settingsor a relative path like../settings. - object: An object with a
pathnameand optionalparams. Thepathnamecan be a full path like/profile/settingsor a relative path like../settings. The params can be an object of key-value pairs.
An Href can either be a string or an object.
Generic: T
Type: T ? T[href] : string | HrefObject
| Property | Type | Description |
|---|---|---|
| params(optional) | UnknownInputParams | Optional parameters for the route. |
| pathname | string | The path of the route. |
| Property | Type | Description |
|---|---|---|
| config(optional) | {
initialRouteName: keyof ParamList,
path: string,
screens: PathConfigMap<ParamList>
} | Config to fine-tune how to parse the path. Example
|
| enabled(optional) | boolean | Whether deep link handling should be enabled. Defaults to true. |
| filter(optional) | (url: string) => boolean | Optional function which takes an incoming URL returns a boolean indicating whether React Navigation should handle it. This can be used to disable deep linking for specific URLs. e.g. URLs used for authentication, and not for deep linking to screens. This is not supported on Web. Example
|
| getActionFromState(optional) | getActionFromStateDefault | Custom function to convert the state object to a valid action (advanced). |
| getInitialURL(optional) | () => string | null | undefined | Promise<string | null | undefined> | Custom function to get the initial URL used for linking.
Uses This is not supported on Web. Example
|
| getPathFromState(optional) | getPathFromStateDefault | Custom function to convert the state object to a valid URL (advanced). Only applicable on Web. |
| getStateFromPath(optional) | getStateFromPathDefault | Custom function to parse the URL to a valid navigation state (advanced). |
| prefixes | string[] | The prefixes are stripped from the URL before parsing them.
Usually they are the This is not supported on Web. Example
|
| subscribe(optional) | (listener: (url: string) => void) => undefined | void | () => void | Custom function to get subscribe to URL updates.
Uses This is not supported on Web. Example
|
Created by using a special file called +native-intent.tsx at the top-level of your
project's app directory. It exports redirectSystemPath or legacy_subscribe functions,
both methods designed to handle URL/path processing.
Useful for re-writing URLs to correctly target a route when unique/referred URLs are incoming from third-party providers or stale URLs from previous versions.
See: For more information on how to use
NativeIntent, see Customizing links.
| Property | Type | Description |
|---|---|---|
| legacy_subscribe(optional) | (listener: (url: string) => void) => undefined | void | () => void |
Useful as an alternative API when a third-party provider doesn't support Expo Router
but has support for React Navigation via Using this API is not recommended for newer projects or integrations since it is incompatible with Server Side Routing and Static Rendering, and can become challenging to manage while offline or in a low network environment. |
| redirectSystemPath(optional) | (event: {
initial: boolean,
path: string
}) => Promise<string | null> | string | null | A special method used to process URLs in native apps. When invoked, it receives an
Its return value should be a Note that throwing errors within this method may result in app crashes. It's recommended to
wrap your code inside a
|
Type: Descriptor<NativeStackNavigationOptions, NativeStackNavigationProp<ParamListBase>, RouteProp<ParamListBase>>
| Property | Type | Description |
|---|---|---|
| key(index signature) | NativeStackDescriptor | - |
Literal Type: union
An item that can be displayed in the header. It can be a button, a menu, spacing, or a custom element.
On iOS 26, when showing items on the right side of the header,
if the items don't fit the available space, they will be collapsed into a menu automatically.
Items with type: 'custom' will not be included in this automatic collapsing behavior.
Acceptable values are: NativeStackHeaderItemButton | NativeStackHeaderItemMenu | NativeStackHeaderItemSpacing | NativeStackHeaderItemCustom
A button item in the header.
Type: SharedHeaderItem extended by:
| Property | Type | Description |
|---|---|---|
| onPress | () => void | Function to call when the item is pressed. |
| selected(optional) | boolean | Whether the item is in a selected state. Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/isselected |
| type | 'button' | Type of the item. |
A custom item to display any React Element in the header.
| Property | Type | Description |
|---|---|---|
| element | React.ReactElement | A React Element to display as the item. |
| hidesSharedBackground(optional) | boolean | Whether the background this item may share with other items in the bar should be hidden. Only available from iOS 26.0 and later. Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground |
| type | 'custom' | - |
An item that shows a menu when pressed.
Type: SharedHeaderItem extended by:
| Property | Type | Description |
|---|---|---|
| changesSelectionAsPrimaryAction(optional) | boolean | Whether the menu is a selection menu. Tapping an item in a selection menu will add a checkmark to the selected item. Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/changesselectionasprimaryaction |
| menu | {
items: (NativeStackHeaderItemMenuAction | NativeStackHeaderItemMenuSubmenu)[],
layout: 'default' | 'palette',
multiselectable: boolean,
title: string
} | Menu for the item. |
| type | 'menu' | - |
An action item in a menu.
| Property | Type | Description |
|---|---|---|
| description(optional) | string | The secondary text displayed alongside the label of the menu item. |
| destructive(optional) | boolean | Whether to apply destructive style to the item. Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive |
| disabled(optional) | boolean | Whether to apply disabled style to the item. Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/disabled |
| discoverabilityLabel(optional) | string | An elaborated title that explains the purpose of the action. On iOS, the system displays this title in the discoverability heads-up display (HUD). If this is not set, the HUD displays the title property. Read more: https://developer.apple.com/documentation/uikit/uiaction/discoverabilitytitle |
| hidden(optional) | boolean | Whether to apply hidden style to the item. Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/hidden |
| icon(optional) | PlatformIconIOS | Icon for the menu item. |
| keepsMenuPresented(optional) | boolean | Whether to keep the menu presented after firing the element’s action. Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/keepsmenupresented |
| label | string | Label for the menu item. |
| onPress | () => void | Function to call when the menu item is pressed. |
| state(optional) | 'on' | 'off' | 'mixed' | The state of an action- or command-based menu item. Read more: https://developer.apple.com/documentation/uikit/uimenuelement/state |
| type | 'action' | - |
A submenu item that contains other menu items.
| Property | Type | Description |
|---|---|---|
| destructive(optional) | boolean | Whether to apply destructive style to the menu item. Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive |
| icon(optional) | PlatformIconIOS | Icon for the submenu item. |
| inline(optional) | boolean | Whether the menu is displayed inline with the parent menu. By default, submenus are displayed after expanding the parent menu item. Inline menus are displayed as part of the parent menu as a section. Defaults to Read more: https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline |
| items | [items] | Array of menu items (actions or submenus). |
| label | string | Label for the submenu item. |
| layout(optional) | 'default' | 'palette' | How the submenu items are displayed.
Defaults to Read more: https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette |
| multiselectable(optional) | boolean | Whether multiple items in the submenu can be selected, i.e. in "on" state. Defaults to Read more: https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/singleselection |
| type | 'submenu' | - |
An item to add spacing between other items in the header.
| Property | Type | Description |
|---|---|---|
| spacing | number | The amount of spacing to add. |
| type | 'spacing' | - |
| Property | Type | Description |
|---|---|---|
| gestureCancel | {
data: undefined
} | Event which fires when a swipe back is canceled on iOS. |
| sheetDetentChange | {
data: {
index: number,
stable: boolean
}
} | Event which fires when screen is in sheet presentation & it's detent changes. In payload it caries two fields:
|
| transitionEnd | {
data: {
closing: boolean
}
} | Event which fires when a transition animation ends. |
| transitionStart | {
data: {
closing: boolean
}
} | Event which fires when a transition animation starts. |
Type: NavigationHelpers<ParamListBase, NativeStackNavigationEventMap>
| Property | Type | Description |
|---|---|---|
| animation(optional) | ScreenProps[stackAnimation] | How the screen should animate when pushed or popped. Supported values:
Only supported on iOS and Android. |
| animationDuration(optional) | number | Only for:  iOS Duration (in milliseconds) for the following transition animations on iOS:
Defaults to The duration is not customizable for:
|
| animationMatchesGesture(optional) | boolean | Only for:  iOS Whether the gesture to dismiss should use animation provided to Doesn't affect the behavior of screens presented modally. |
| animationTypeForReplace(optional) | ScreenProps[replaceAnimation] | The type of animation to use when this screen replaces another screen. Defaults to Supported values:
Only supported on iOS and Android. |
| autoHideHomeIndicator(optional) | boolean | Only for:  iOS Whether the home indicator should prefer to stay hidden on this screen. Defaults to |
| contentStyle(optional) | StyleProp<ViewStyle> | Style object for the scene content. |
| freezeOnBlur(optional) | boolean | Whether inactive screens should be suspended from re-rendering. Defaults to Only supported on iOS and Android. |
| fullScreenGestureEnabled(optional) | boolean | Only for:  iOS Whether the gesture to dismiss should work on the whole screen. The behavior depends on iOS version. On iOS 18 and below:
On iOS 26 and up:
Doesn't affect the behavior of screens presented modally. |
| fullScreenGestureShadowEnabled(optional) | boolean |
iOS iOS 18 and below. Controls whether the full screen dismiss gesture has shadow under view during transition.
The gesture uses custom transition and thus doesn't have a shadow by default. When enabled, a custom shadow view
is added during the transition which tries to mimic the default iOS shadow. Defaults to This does not affect the behavior of transitions that don't use gestures, enabled by |
| gestureDirection(optional) | ScreenProps[swipeDirection] | Only for:  iOS Sets the direction in which you should swipe to dismiss the screen.
When using Supported values:
|
| gestureEnabled(optional) | boolean | Only for:  iOS Whether you can use gestures to dismiss this screen. Defaults to Only supported on iOS. |
| gestureResponseDistance(optional) | ScreenProps[gestureResponseDistance] | Only for:  iOS Use it to restrict the distance from the edges of screen in which the gesture should be recognized. To be used alongside |
| header(optional) | (props: NativeStackHeaderProps) => React.ReactNode | Function that given |
| headerBackButtonDisplayMode(optional) | ScreenStackHeaderConfigProps[backButtonDisplayMode] | Only for:  iOS, web How the back button displays icon and title. Supported values:
The space-aware behavior is disabled when:
In such cases, a static title and icon are always displayed. Defaults to "default" on iOS, and "minimal" on other platforms. Only supported on iOS and Web. |
| headerBackButtonMenuEnabled(optional) | boolean | Only for:  iOS Boolean indicating whether to show the menu on longPress of iOS >= 14 back button. Defaults to Only supported on iOS. |
| headerBackground(optional) | () => React.ReactNode | Function which returns a React Element to render as the background of the header.
This is useful for using backgrounds such as an image, a gradient, blur effect etc.
You can use this with |
| headerBackIcon(optional) | {
source: ImageSourcePropType,
type: 'image'
} | Icon to display in the header as the icon in the back button. Defaults to back icon image for the platform
Example
|
| headerBackImageSource(optional) | ImageSourcePropType |
Image to display in the header as the icon in the back button. |
| headerBackTitle(optional) | string | Only for:  iOS, web Title string used by the back button on iOS.
Defaults to the previous scene's title.
On iOS the text might be shortened to "Back" or arrow icon depending on the available space, following native iOS behaviour.
See Only supported on iOS and Web. |
| headerBackTitleStyle(optional) | StyleProp<{
fontFamily: string,
fontSize: number
}> | Only for:  iOS, web Style object for header back title. Supported properties:
Only supported on iOS and Web. |
| headerBackVisible(optional) | boolean | Whether the back button is visible in the header.
You can use it to show a back button alongside This will have no effect on the first screen in the stack. |
| headerBlurEffect(optional) | ScreenStackHeaderConfigProps[blurEffect] | Only for:  iOS Blur effect for the translucent header.
The Note: Using both Only supported on iOS. |
| headerLargeStyle(optional) | StyleProp<{
backgroundColor: ColorValue
}> | Only for:  iOS Style of the header when a large title is shown.
The large title is shown if Supported properties:
Only supported on iOS. |
| headerLargeTitle(optional) | boolean |
Whether to enable header with large title which collapses to regular header on scroll. |
| headerLargeTitleEnabled(optional) | boolean | Only for:  iOS Whether to enable header with large title which collapses to regular header on scroll. For large title to collapse on scroll, the content of the screen should be wrapped in a scrollable view such as Only supported on iOS. |
| headerLargeTitleShadowVisible(optional) | boolean | Only for:  iOS Whether drop shadow of header is visible when a large title is shown. Only supported on iOS. |
| headerLargeTitleStyle(optional) | StyleProp<{
color: ColorValue,
fontFamily: string,
fontSize: number,
fontWeight: string
}> | Only for:  iOS Style object for large title in header. Supported properties:
Only supported on iOS. |
| headerLeft(optional) | (props: NativeStackHeaderBackProps) => React.ReactNode | Function which returns a React Element to display on the left side of the header.
This replaces the back button. See |
| headerRight(optional) | (props: NativeStackHeaderItemProps) => React.ReactNode | Function which returns a React Element to display on the right side of the header.
Will be overriden by |
| headerSearchBarOptions(optional) | SearchBarProps | Options to render a native search bar.
You also need to specify |
| headerShadowVisible(optional) | boolean | Whether to hide the elevation shadow (Android) or the bottom border (iOS) on the header. |
| headerShown(optional) | boolean | Whether to show the header. The header is shown by default.
Setting this to |
| headerStyle(optional) | StyleProp<{
backgroundColor: ColorValue
}> | Style object for header. Supported properties:
|
| headerTintColor(optional) | ColorValue | Tint color for the header. Changes the color of back button and title. |
| headerTitle(optional) | string | (props: {
children: string,
tintColor: ColorValue
}) => React.ReactNode | String or a function that returns a React Element to be used by the header.
Defaults to screen When a function is passed, it receives Note that if you render a custom element by passing a function, animations for the title won't work. |
| headerTitleAlign(optional) | 'left' | 'center' | How to align the the header title.
Defaults to Not supported on iOS. It's always |
| headerTitleStyle(optional) | StyleProp<Pick<TextStyle, 'fontFamily' | 'fontSize' | 'fontWeight'> & {
color: ColorValue
}> | Style object for header title. Supported properties:
|
| headerTransparent(optional) | boolean | Boolean indicating whether the navigation bar is translucent.
Setting this to |
| keyboardHandlingEnabled(optional) | boolean | Only for:  iOS Whether the keyboard should hide when swiping to the previous screen. Defaults to |
| navigationBarColor(optional) | ColorValue |
Android Sets the navigation bar color. Defaults to initial navigation bar color. |
| navigationBarHidden(optional) | boolean | Only for:  Android Sets the visibility of the navigation bar. Defaults to |
| navigationBarTranslucent(optional) | boolean |
Android Boolean indicating whether the content should be visible behind the navigation bar. Defaults to |
| orientation(optional) | ScreenProps[screenOrientation] | The display orientation to use for the screen. Supported values:
Only supported on iOS and Android. |
| presentation(optional) | Exclude<ScreenProps[stackPresentation], 'push'> | 'card' | How should the screen be presented. Supported values:
Only supported on iOS and Android. |
| scrollEdgeEffects(optional) | {
bottom: ScrollEdgeEffect,
left: ScrollEdgeEffect,
right: ScrollEdgeEffect,
top: ScrollEdgeEffect
} | Only for:  iOS Configures the scroll edge effect for the content ScrollView (the ScrollView that is present in first descendants chain of the Screen). Depending on values set, it will blur the scrolling content below certain UI elements (header items, search bar) for the specified edge of the ScrollView. When set in nested containers, i.e. Native Stack inside Native Bottom Tabs, or the other way around, the ScrollView will use only the innermost one's config. Note: Using both Edge effects can be configured for each edge separately. The following values are currently supported:
Defaults to |
| sheetAllowedDetents(optional) | number[] | 'fitToContents' | Describes heights where a sheet can rest.
Works only when Heights should be described as fraction (a number from There is also possibility to specify Note that the array must be sorted in ascending order. This invariant is verified only in developement mode, where violation results in error. Android is limited to up 3 values in the array -- any surplus values, beside first three are ignored. Defaults to |
| sheetCornerRadius(optional) | number | The corner radius that the sheet will try to render with.
Works only when If set to non-negative value it will try to render sheet with provided radius, else it will apply system default. If left unset system default is used. |
| sheetElevation(optional) | number | Only for:  Android Integer value describing elevation of the sheet, impacting shadow on the top edge of the sheet. Not dynamic - changing it after the component is rendered won't have an effect. Defaults to |
| sheetExpandsWhenScrolledToEdge(optional) | boolean | Only for:  iOS Whether the sheet should expand to larger detent when scrolling.
Works only when |
| sheetGrabberVisible(optional) | boolean | Only for:  iOS Boolean indicating whether the sheet shows a grabber at the top.
Works only when |
| sheetInitialDetentIndex(optional) | number | 'last' | Index of the detent the sheet should expand to after being opened.
Works only when If the specified index is out of bounds of Additionaly there is Defaults to |
| sheetLargestUndimmedDetentIndex(optional) | number | 'none' | 'last' | The largest sheet detent for which a view underneath won't be dimmed.
Works only when This prop can be set to an number, which indicates index of detent in Additionaly there are following options available:
|
| sheetResizeAnimationEnabled(optional) | boolean | Only for:  Android Whether the default native animation should be used when the sheet's with
When set to When set to Defaults to |
| sheetShouldOverflowTopInset(optional) | boolean | Only for:  Android Whether the sheet content should be rendered behind the Status Bar or display cutouts. When set to When set to Defaults to |
| statusBarAnimation(optional) | ScreenProps[statusBarAnimation] | Only for:  android, iOS Sets the status bar animation (similar to the Defaults to Only supported on Android and iOS. |
| statusBarBackgroundColor(optional) | ColorValue |
Android Sets the status bar color (similar to the |
| statusBarHidden(optional) | boolean | Only for:  android, iOS Whether the status bar should be hidden on this screen.
Requires setting Only supported on Android and iOS. |
| statusBarStyle(optional) | ScreenProps[statusBarStyle] | Only for:  android, iOS Sets the status bar color (similar to the Defaults to Only supported on Android and iOS. |
| statusBarTranslucent(optional) | boolean |
Android Sets the translucency of the status bar. Defaults to |
| title(optional) | string | String that can be displayed in the header as a fallback for |
| unstable_headerLeftItems(optional) | (props: NativeStackHeaderItemProps) => NativeStackHeaderItem[] | Only for:  iOS Function which returns an array of items to display as on the left side of the header.
Overrides This is an unstable API and might change in the future. |
| unstable_headerRightItems(optional) | (props: NativeStackHeaderItemProps) => NativeStackHeaderItem[] | Only for:  iOS Function which returns an array of items to display as on the right side of the header.
Overrides This is an unstable API and might change in the future. |
| unstable_sheetFooter(optional) | () => React.ReactNode | Only for:  Android Footer component that can be used alongside formSheet stack presentation style. This option is provided, because due to implementation details it might be problematic to implement such layout with JS-only code. Note that this prop is marked as unstable and might be subject of breaking changes, including removal, in particular when we find solution that will make implementing it with JS straightforward. |
Literal Type: union
Acceptable values are: NavigationProp<ParamList, RouteName, NavigatorID, StackNavigationState<ParamList>, NativeStackNavigationOptions, NativeStackNavigationEventMap> | StackActionHelpers<ParamList>
Type: NativeStackScreenProps<ParamList, RouteName, NavigatorID> extended by:
| Property | Type | Description |
|---|---|---|
| theme | Theme | - |
| Property | Type | Description |
|---|---|---|
| __unsafe_action__ | {
data: {
action: NavigationAction,
noop: boolean,
stack: string | undefined
}
} | Event that fires when an action is dispatched. Only intended for debugging purposes, don't use it for app logic. This event will be emitted before state changes have been applied. |
| options | {
data: {
options: object
}
} | Event that fires when current options changes. |
| ready | {
data: undefined
} | Event that fires when the navigation container is ready to be used. |
| state | {
data: {
state: NavigationState | PartialState<NavigationState> | undefined
}
} | Event that fires when the navigation state changes. |
Type: NavigationHelpers<ParamList> EventConsumer<NavigationContainerEventMap> extended by:
| Property | Type | Description |
|---|---|---|
| getCurrentOptions | () => object | undefined | Get the currently focused route's options. |
| getCurrentRoute | () => MaybeParamListRoute<ParamList> | undefined | Get the currently focused navigation route. |
| getParent | () => undefined | Stub function for getParent on navigation object for use with useNavigation. |
| getRootState | () => NavigationState | Get the rehydrated navigation state of the navigation tree. |
| isReady | () => boolean | Whether the navigation container is ready to handle actions. |
| resetRoot | (state?: Readonly<{
history: unknown[],
index: number,
key: string,
routeNames: Extract[],
routes: NavigationRoute[],
stale: false,
type: string
}> | PartialState<Readonly<{
history: unknown[],
index: number,
key: string,
routeNames: Extract[],
routes: NavigationRoute[],
stale: false,
type: string
}>>) => void | Reset the navigation state of the root navigator to the provided state. |
| setOptions | () => never | Stub function for setOptions on navigation object for use with useNavigation. |
Type: NavigationContainerRef<ParamList> extended by:
| Property | Type | Description |
|---|---|---|
| current | NavigationContainerRef<ParamList> | null | - |
Literal Type: union
Acceptable values are: NavigationHelpersCommon<ParamList> | EventEmitter<EventMap> | NavigationHelpersRoute<ParamList, keyof ParamList>
Type: Omit<NavigationHelpersCommon<ParamList, State>, 'getParent'> NavigationHelpersRoute<ParamList, RouteName> EventConsumer<EventMap & EventMapCore<State>> PrivateValueStore<[ParamList, RouteName, EventMap]> extended by:
| Property | Type | Description |
|---|---|---|
| getParent | (id?: NavigatorID) => T | Returns the navigation prop from a parent navigator based on the ID. If an ID is provided, the navigation prop from the parent navigator with matching ID (including current) will be returned. If no ID is provided, the navigation prop from the immediate parent navigator will be returned. |
| setOptions | (options: Partial<ScreenOptions>) => void | Update the options for the route. The options object will be shallow merged with default options object. |
Type: object shaped as below:
| Property | Type | Description |
|---|---|---|
| initial(optional) | never | - |
| merge(optional) | never | - |
| params(optional) | never | - |
| path(optional) | string | - |
| pop(optional) | never | - |
| screen(optional) | never | - |
| state | PartialState<NavigationState> | NavigationState | undefined | - |
| Property | Type | Description |
|---|---|---|
| EventMap | EventMap | - |
| NavigationList | NavigationList | - |
| Navigator | Navigator | - |
| NavigatorID | NavigatorID | - |
| ParamList | ParamList | - |
| ScreenOptions | ScreenOptions | - |
| State | State | - |
| Property | Type | Description |
|---|---|---|
| EventMap | undefined | - |
| NavigationList | NavigationListBase<ParamListBase> | - |
| Navigator | React.ComponentType<any> | - |
| NavigatorID | string | undefined | - |
| ParamList | undefined | - |
| ScreenOptions | undefined | - |
| State | NavigationState | - |
Type: Partial<PathConfigAlias> extended by:
| Property | Type | Description |
|---|---|---|
| alias(optional) | (string | PathConfigAlias)[] | Additional path alias that will be matched to the same screen. |
| initialRouteName(optional) | keyof ParamList | Name of the initial route to use for the navigator when the path matches. |
| screens(optional) | PathConfigMap<ParamList> | Path configuration for child screens. |
| stringify(optional) | Record<string, (value: any) => string> | An object mapping the param name to a function which converts the param value to a string.
By default, all params are converted to strings using Example
|
Literal Type: union
The list of input keys will become optional, everything else will remain the same.
| Property | Type | Description |
|---|---|---|
| destination | string | - |
| destinationContextKey | string | - |
| external(optional) | boolean | - |
| methods(optional) | string[] | - |
| permanent(optional) | boolean | - |
| source | string | - |
Literal Type: union
Acceptable values are: ./{string} | ../{string} | '..'
Type: PartialState<NavigationState> extended by:
| Property | Type | Description |
|---|---|---|
| state(optional) | ResultState | - |
Type: Exclude<Extract[pathname], RelativePathString | ExternalPathString>
Literal Type: union
Acceptable values are: RouteConfigProps<ParamList, RouteName, State, ScreenOptions, EventMap, Navigation> | RouteConfigComponent<ParamList, RouteName>
Type: object shaped as below:
| Property | Type | Description |
|---|---|---|
| children(optional) | never | - |
| component | ScreenComponentType<ParamList, RouteName> | React component to render for this screen. |
| getComponent(optional) | never | - |
Or object shaped as below:
| Property | Type | Description |
|---|---|---|
| children(optional) | never | - |
| component(optional) | never | - |
| getComponent | () => ScreenComponentType<ParamList, RouteName> | Lazily get a React component to render for this screen. |
Or object shaped as below:
| Property | Type | Description |
|---|---|---|
| children | (props: {
navigation: any,
route: RouteProp<ParamList, RouteName>
}) => React.ReactNode | Render callback to render content of this screen. |
| component(optional) | never | - |
| getComponent(optional) | never | - |
| Property | Type | Description |
|---|---|---|
| children | React.ReactNode | Children React Elements to extract the route configuration from.
Only |
| navigationKey(optional) | string | Optional key for the screens in this group. If the key changes, all existing screens in this group will be removed or reset. |
| screenLayout(optional) | (props: ScreenLayoutArgs<ParamList, keyof ParamList, ScreenOptions, Navigation>) => React.ReactElement | undefined | Layout for the screens inside the group.
This will override the |
| screenOptions(optional) | ScreenOptions | (props: {
navigation: Navigation,
route: RouteProp<ParamList, keyof ParamList>,
theme: ReactNavigation.Theme
}) => ScreenOptions | Navigator options for this screen. |
Returns router object for imperative navigation API.
Example
import { router } from 'expo-router'; import { Text } from 'react-native'; export default function Route() { return ( <Text onPress={() => router.push('/home')}>Go Home</Text> ); }
| Property | Type | Description |
|---|---|---|
| back | () => void | Goes back in the navigation history. |
| canDismiss | () => boolean | Checks if it is possible to dismiss the current screen. Returns |
| canGoBack | () => boolean | Navigates to a route in the navigator's history if it supports invoking the |
| dismiss | (count: number) => void | Navigates to the a stack lower than the current screen using the provided count if possible, otherwise 1. If the current screen is the only route, it will dismiss the entire stack. |
| dismissAll | () => void | Returns to the first screen in the closest stack. This is similar to
|
| dismissTo | (href: Href, options: NavigationOptions) => void | Dismisses screens until the provided href is reached. If the href is not found, it will instead replace the current screen with the provided |
| navigate | (href: Href, options: NavigationOptions) => void | Navigates to the provided |
| prefetch | (name: Href) => void | Prefetch a screen in the background before navigating to it |
| push | (href: Href, options: NavigationOptions) => void | Navigates to the provided |
| replace | (href: Href, options: NavigationOptions) => void | Navigates to route without appending to the history. Can be used with
|
| setParams | (params: Partial<RouteInputParams<T>>) => void | Updates the current route's query params. |
| Property | Type | Description |
|---|---|---|
| children | React.ReactElement | - |
| navigation | Navigation | - |
| options | ScreenOptions | - |
| route | RouteProp<ParamList, RouteName> | - |
| theme | ReactNavigation.Theme | - |
Type: Partial<undefined>
| Property | Type | Description |
|---|---|---|
| dangerouslySingular(optional) | SingularOptions | - |
| getId(optional) | ({ params }: {
params: Record<string, any>
}) => string | undefined | - |
| initialParams(optional) | Record<string, any> | - |
| listeners(optional) | ScreenListeners<TState, TEventMap> | (prop: {
navigation: any,
route: RouteProp<ParamListBase, string>
}) => ScreenListeners<TState, TEventMap> | - |
| name(optional) | string | Name is required when used inside a Layout component. |
| options(optional) | TOptions | (prop: {
navigation: any,
route: RouteProp<ParamListBase, string>
}) => TOptions | - |
| redirect(optional) | boolean | Redirect to the nearest sibling route.
If all children are |
| Property | Type | Description |
|---|---|---|
| getCurrentOptions | () => Record<string, any> | undefined | - |
Type: boolean or object shaped as below:
(name, params) => string | undefined
string | undefined| Parameter | Type | Description |
|---|---|---|
| name(index signature) | string | - |
| params(index signature) | UnknownOutputParams | - |
| Property | Type | Description |
|---|---|---|
| children | SitemapType[] | - |
| contextKey | string | - |
| filename | string | - |
| href | string | Href | - |
| isGenerated | boolean | - |
| isInitial | boolean | - |
| isInternal | boolean | - |
Type: NativeTheme
| Property | Type | Description |
|---|---|---|
| EventMap | EventMap | - |
| NavigationList | NavigationList | - |
| Navigator | Navigator | - |
| NavigatorID | NavigatorID | - |
| ParamList | ParamList | - |
| ScreenOptions | ScreenOptions | - |
| State | State | - |
Literal Type: TypedNavigatorInternal
Acceptable values are: TypedNavigatorInternal<Bag[ParamList], Bag[NavigatorID], Bag[State], Bag[ScreenOptions], Bag[EventMap], Bag[NavigationList], Bag[Navigator]>