Reference version

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.

Android
iOS
tvOS
Web
Included in Expo Go

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.

Expo Router guides

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:

Install Expo Router

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

app.json
{ "expo": { "plugins": ["expo-router"] } }

Configurable properties

NameDefaultDescription
root"app"

Changes the routes directory from app to another value. Avoid using this property unless you have a specific need.

originundefined

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.

headOriginundefined

A more specific origin URL used in the expo-router/head module for iOS handoff. Defaults to origin.

asyncRoutesundefined

Enable async routes (lazy loading). Can be a boolean, a string ("development" or "production"), or an object with platform-specific values ({ android, ios, web, default }). production is currently web-only and will be disabled on native.

platformRoutestrue

Enable or disable platform-specific routes (for example, index.android.tsx and index.ios.tsx).

sitemaptrue

Enable or disable the automatically generated sitemap at /_sitemap.

partialRouteTypestrue

Enable partial typed routes generation. This allows TypeScript to provide type checking for routes without requiring all routes to be statically known.

redirectsundefined

An array of static redirect rules. Each rule should have source, destination, and optionally permanent (defaults to false) and methods (HTTP methods to redirect).

rewritesundefined

An array of static rewrite rules. Each rule should have source, destination, and optionally methods (HTTP methods to rewrite).

headersundefined

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.

disableSynchronousScreensUpdatesfalse

Disable synchronous layout updates for native screens. This can help with performance in some cases.

unstable_useServerMiddlewarefalse
Experimental

Enable server middleware support with a +middleware.ts file. Requires web.output: "server" to be set in app config.

unstable_useServerDataLoadersfalse
Experimental

Enable data loader support. This is only supported for web.output: "static" outputs at the moment.

unstable_useServerRenderingfalse
Experimental

Enable server-side rendering. When enabled with web.output: "server", HTML is rendered at request time instead of being pre-rendered at build time.

Usage

For information core concepts, notation patterns, navigation layouts, and common navigation patterns, start with Router 101 section:

Router 101

APIs

APIDescription
StackStack navigator, toolbar, and screen components
LinkLink and Redirect components
ColorPlatform color utilities
Native TabsNative tab navigation
Split ViewSplit view layout
UIHeadless tab components

API

import { useRouter, Tabs, Navigator, Slot } from 'expo-router';

Components

Tabs

Android
iOS
tvOS
Web

Renders a tabs navigator.

Badge

Android
iOS
tvOS
Web

Type: React.Element<BadgeProps>

BadgeProps

ErrorBoundary

Android
iOS
tvOS
Web

Type: React.Element<ErrorBoundaryProps>

Props passed to a page's ErrorBoundary export.

ErrorBoundaryProps

error

Android
iOS
tvOS
Web
Type: Error

The error that was thrown.

retry

Android
iOS
tvOS
Web
Type: () => Promise<void>

A function that will re-render the route component by clearing the error state.

Icon

Android
iOS
tvOS
Web

Type: React.Element<IconProps>

IconProps

Label

Android
iOS
tvOS
Web

Type: React.Element<LabelProps>

LabelProps

Slot

Android
iOS
tvOS
Web

Type: React.Element<Omit<NavigatorProps<any>, 'children'>>

Renders the currently selected content.

There are actually two different implementations of <Slot/>:

  • Used inside a _layout as the Navigator
  • Used inside a Navigator as 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.

ThemeProvider

Android
iOS
tvOS
Web

Type: React.Element<Props>

VectorIcon

Android
iOS
tvOS
Web

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" />} />

VectorIconProps

family

Android
iOS
tvOS
Web
Type: { getImageSource: (name: NameT, size: number, color: ColorValue) => Promise<ImageSourcePropType | null> }

The family of the vector icon.

Example

import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';

name

Android
iOS
tvOS
Web
Type: NameT

The name of the vector icon.

Tabs.Screen

Android
iOS
tvOS
Web

Type: React.Element<ScreenProps<TabsProps, TabNavigationState<ParamListBase>, BottomTabNavigationEventMap>>

Constants

DarkTheme

Android
iOS
tvOS
Web

Type: Theme

DefaultTheme

Android
iOS
tvOS
Web

Type: Theme

unstable_navigationEvents

Android
iOS
tvOS
Web

Type: { addListener: (eventType: EventType, callback: (event: Payload<EventType>) => void) => () => void, emit: (type: EventType, event: Payload<EventType>) => void, enable: () => void, isEnabled: () => boolean, saveCurrentPathname: () => void, }

Hooks

useFocusEffect(effect, do_not_pass_a_second_prop)

Android
iOS
tvOS
Web
ParameterTypeDescription
effectEffectCallback

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.

Returns:
void

Example

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 </>; }

useGlobalSearchParams()

Android
iOS
tvOS
Web

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.

Returns:
RouteParams<TRoute> & TParams

Example

app/profile/[user].tsx
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>; }

useIsFocused()

Android
iOS
tvOS
Web

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.

Returns:
boolean

useLoaderData()

Android
iOS
tvOS
Web

Returns the result of the loader function for the calling route.

Returns:
LoaderFunctionResult<T>

Example

app/profile/[user].tsx
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>; }

useLocalSearchParams()

Android
iOS
tvOS
Web

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.

Returns:
RouteParams<TRoute> & TParams

Example

app/profile/[user].tsx
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>; }

useNavigation(parent)

Android
iOS
tvOS
Web
ParameterTypeDescription
parent(optional)string | HrefObject

Provide an absolute path such as /(root) to the parent route or a relative path like ../../ to the parent route.


Returns the underlying React Navigation navigation object to imperatively access layout-specific functionality like navigation.openDrawer() in a Drawer layout.

Returns:
T

The navigation object for the current route.

See: React Navigation documentation on navigation dependent functions for more information.

Example

app/index.tsx
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

app/orders/menu/index.tsx
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.

useNavigationBuilder(createRouter, options)

Android
iOS
tvOS
Web
ParameterTypeDescription
createRouterRouterFactory<State, Readonly<{ payload: object, source: string, target: string, type: string }>, RouterOptions>

Factory method which returns router object.

optionsDefaultNavigatorOptions<ParamListBase, string | undefined, State, ScreenOptions, EventMap, any> & RouterOptions

Options object containing children and additional options for the router.


Hook for building navigators.

Returns:
{ 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.

useNavigationContainerRef()

Android
iOS
tvOS
Web
Returns:
NavigationContainerRefWithCurrent<RootParamList>

The root <NavigationContainer /> ref for the app. The ref.current may be null if the <NavigationContainer /> hasn't mounted yet.

useNavigationState(selector)

Android
iOS
tvOS
Web
ParameterTypeDescription
selectorSelector<ParamList, T>

Selector function to get a value from the state.


Hook to get a value from the current navigation state using a selector.

Returns:
T

usePathname()

Android
iOS
tvOS
Web

Returns 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.

Returns:
string

Example

app/profile/[user].tsx
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>; }

usePreventRemove(preventRemove, callback)

Android
iOS
tvOS
Web
ParameterTypeDescription
preventRemoveboolean

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.

Returns:
void

Deprecated: Use useNavigationContainerRef instead, which returns a React ref.

useRootNavigation()

Android
iOS
tvOS
Web

useRootNavigationState()

Android
iOS
tvOS
Web

Returns the navigation state of the navigator which contains the current screen.

Example

import { useRootNavigationState } from 'expo-router'; export default function Route() { const { routes } = useRootNavigationState(); return <Text>{routes[0].name}</Text>; }

useRoute()

Android
iOS
tvOS
Web

Hook to access the route prop of the parent screen anywhere.

Returns:
T

Route prop of the parent screen.

useRouter()

Android
iOS
tvOS
Web

Returns the Router object for imperative navigation.

Returns:
Router

Example

import { useRouter } from 'expo-router'; import { Text } from 'react-native'; export default function Route() { const router = useRouter(); return ( <Text onPress={() => router.push('/home')}>Go Home</Text> ); }

useScrollToTop(ref)

Android
iOS
tvOS
Web
ParameterType
refRefObject<ScrollableWrapper>

Returns:
void

useSegments()

Android
iOS
tvOS
Web

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]"].

Returns:
RouteSegments<TSegments>

Example

app/profile/[user].tsx
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']>()

useSitemap()

Android
iOS
tvOS
Web
Returns:
SitemapType | null

useTheme()

Android
iOS
tvOS
Web
Returns:
Theme

Classes

PrivateValueStore

Android
iOS
tvOS
Web

Methods

Deprecated: This function may be replaced in the future version of expo-router.

createNavigatorFactory(Navigator)

Android
iOS
tvOS
Web
ParameterTypeDescription
NavigatorComponentType<any>

The navigator component. Should be wrapped with withLayoutContext.


Higher order component to create a Navigator and Screen pair. Custom navigators should wrap the navigator component in createNavigator before exporting.

Returns:
(config: any) => any

Factory method to create a Navigator and Screen pair.

Sitemap()

Android
iOS
tvOS
Web
Returns:
Element

TabRouter(args)

Android
iOS
tvOS
Web
ParameterType
argsTabRouterOptions

TabRouter is considered an internal implementation and its behavior may change without a notice between expo-router's version

Returns:
Router<TabNavigationState<ParamListBase>, Action | TabActionType>

withLayoutContext(Nav, processor, useOnlyUserDefinedScreens)

Android
iOS
tvOS
Web
ParameterTypeDescription
NavT

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.

Returns:
Component<PropsWithoutRef<PickPartial<ComponentProps<T>, 'children'>>> & { Protected: FunctionComponent<ProtectedProps>, Screen: (props: ScreenProps<TOptions, TState, TEventMap>) => null }

Example

app/_layout.tsx
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

CompositeNavigationProp

Android
iOS
tvOS
Web

Literal Type: union

Acceptable values are: Omit<A & B, keyof NavigationProp<any>> | NavigationProp<undefined & undefined, undefined, undefined | undefined, undefined, undefined, undefined>

DefaultNavigatorOptions

Android
iOS
tvOS
Web

Type: DefaultRouterOptions<Keyof<ParamList>> extended by:

PropertyTypeDescription
childrenReact.ReactNode

Children React Elements to extract the route configuration from. Only Screen, Group and React.Fragment are supported as children.

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.

  • 'firstMatch': Navigate to the first route in the new list of routes (default).
  • 'lastUnhandled': Restore the last state that was unhandled due to conditional render.

Example cases where previous state might have been unhandled:

  • Opened a deep link to a screen, but a login screen was shown.
  • Navigated to a screen containing a navigator, but a different screen was shown.
  • Reset the navigator to a state with different routes not matching the current list of routes.

In these cases, 'lastUnhandled' will reuse the unhandled state if present. If there's no unhandled state, it will fallback to 'firstMatch' behavior.

Caveats:

  • Direct navigation is only handled for NAVIGATE actions.
  • Unhandled state is restored only if the current state becomes invalid, i.e. it doesn't contain any currently defined screens.
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.

Descriptor

Android
iOS
tvOS
Web
PropertyTypeDescription
navigationNavigation

Navigation object for the screen

optionsScreenOptions

Options for the route.

routeRoute

Route object for the screen

render() => Element

Render the component associated with this route.

DocumentTitleOptions

Android
iOS
tvOS
Web
PropertyTypeDescription
enabled(optional)boolean
-
formatter(optional)(options: Record<string, any> | undefined, route: Route<string> | undefined) => string
-

EffectCallback()

Android
iOS
tvOS
Web

Memoized callback containing the effect, should optionally return a cleanup function.

Returns:

undefined | void | () => void

EventArg

Android
iOS
tvOS
Web

Type: extended by:

PropertyTypeDescription
target(optional)string
-
typeEventName

Type of the event (e.g. focus, blur)

EventConsumer

Android
iOS
tvOS
Web
PropertyTypeDescription
addListener(type: EventName, callback: EventListenerCallback<EventMap, EventName>) => () => void

Subscribe to events from the parent navigator.

removeListener(type: EventName, callback: EventListenerCallback<EventMap, EventName>) => void
-

EventEmitter

Android
iOS
tvOS
Web
PropertyTypeDescription
emit(options: { target: string, type: EventName } & undefined & undefined) => EventArg<EventName, [canPreventDefault], [data]>

Emit an event to child screens.

EventListenerCallback(e)

Android
iOS
tvOS
Web
ParameterType
eEventArg<EventName, undefined, [data]>
Returns:

void

EventMapBase

Android
iOS
tvOS
Web

Type: Record<string, { canPreventDefault: boolean, data: any }>

EventMapCore

Android
iOS
tvOS
Web
PropertyTypeDescription
beforeRemove{ canPreventDefault: true, data: { action: NavigationAction } }
-
blur{ data: undefined }
-
focus{ data: undefined }
-
state{ data: { state: State } }
-

ExternalPathString

Android
iOS
tvOS
Web

Literal Type: union

Acceptable values are: {string}:{string} | //{string}

Href<T>

Android
iOS
tvOS
Web

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/settings or a relative path like ../settings.
  • object: An object with a pathname and optional params. The pathname can be a full path like /profile/settings or 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

HrefObject

Android
iOS
tvOS
Web
PropertyTypeDescription
params(optional)UnknownInputParams

Optional parameters for the route.

pathnamestring

The path of the route.

LinkingOptions

Android
iOS
tvOS
Web
PropertyTypeDescription
config(optional){ initialRouteName: keyof ParamList, path: string, screens: PathConfigMap<ParamList> }

Config to fine-tune how to parse the path.

Example

{ Chat: { path: 'chat/:author/:id', parse: { id: Number } } }
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

{ // Filter out URLs used by expo-auth-session filter: (url) => !url.includes('+expo-auth-session') }
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 Linking.getInitialURL() by default.

This is not supported on Web.

Example

{ getInitialURL () => Linking.getInitialURL(), }
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).

prefixesstring[]

The prefixes are stripped from the URL before parsing them. Usually they are the scheme + host (e.g. myapp://chat?user=jane)

This is not supported on Web.

Example

{ prefixes: [ "myapp://", // App-specific scheme "https://example.com", // Prefix for universal links "https://*.example.com" // Prefix which matches any subdomain ] }
subscribe(optional)(listener: (url: string) => void) => undefined | void | () => void

Custom function to get subscribe to URL updates. Uses Linking.addEventListener('url', callback) by default.

This is not supported on Web.

Example

{ subscribe: (listener) => { const onReceiveURL = ({ url }) => listener(url); Linking.addEventListener('url', onReceiveURL); return () => Linking.removeEventListener('url', onReceiveURL); } }

LocaleDirection

Android
iOS
tvOS
Web

Literal Type: string

Acceptable values are: 'ltr' | 'rtl'

NativeIntent

Android
iOS
tvOS
Web

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.

PropertyTypeDescription
legacy_subscribe(optional)(listener: (url: string) => void) => undefined | void | () => void
Experimentally available in SDK 52.

Useful as an alternative API when a third-party provider doesn't support Expo Router but has support for React Navigation via Linking.subscribe() for existing projects.

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 options object with the following properties:

  • path: represents the URL or path undergoing processing.
  • initial: a boolean indicating whether the path is the app's initial URL.

Its return value should be a string, a Promise<string | null>, or null. When a falsy value is returned (for example, null), no redirection occurs and the app stays on the current path.

Note that throwing errors within this method may result in app crashes. It's recommended to wrap your code inside a try/catch block and utilize .catch() when appropriate.

See: For usage information, see Redirecting system paths.

NativeStackDescriptor

Android
iOS
tvOS
Web

Type: Descriptor<NativeStackNavigationOptions, NativeStackNavigationProp<ParamListBase>, RouteProp<ParamListBase>>

NativeStackDescriptorMap

Android
iOS
tvOS
Web
PropertyTypeDescription
key(index signature)NativeStackDescriptor
-

NativeStackHeaderItem

Android
iOS
tvOS
Web

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

NativeStackHeaderItemButton

Android
iOS
tvOS
Web

A button item in the header.

Type: SharedHeaderItem extended by:

PropertyTypeDescription
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.

NativeStackHeaderItemCustom

Android
iOS
tvOS
Web

A custom item to display any React Element in the header.

PropertyTypeDescription
elementReact.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'
-

NativeStackHeaderItemMenu

Android
iOS
tvOS
Web

An item that shows a menu when pressed.

Type: SharedHeaderItem extended by:

PropertyTypeDescription
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'
-

NativeStackHeaderItemMenuAction

Android
iOS
tvOS
Web

An action item in a menu.

PropertyTypeDescription
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

labelstring

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'
-

NativeStackHeaderItemMenuSubmenu

Android
iOS
tvOS
Web

A submenu item that contains other menu items.

PropertyTypeDescription
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 false.

Read more: https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline

items[items]

Array of menu items (actions or submenus).

labelstring

Label for the submenu item.

layout(optional)'default' | 'palette'

How the submenu items are displayed.

  • default: menu items are displayed normally.
  • palette: menu items are displayed in a horizontal row.

Defaults to default.

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 false.

Read more: https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/singleselection

type'submenu'
-

NativeStackHeaderItemSpacing

Android
iOS
tvOS
Web

An item to add spacing between other items in the header.

PropertyTypeDescription
spacingnumber

The amount of spacing to add.

type'spacing'
-

NativeStackNavigationConfig

Android
iOS
tvOS
Web

NativeStackNavigationEventMap

Android
iOS
tvOS
Web
PropertyTypeDescription
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:

  • index - current detent index in the sheetAllowedDetents array,
  • stable - on Android false value means that the user is dragging the sheet or it is settling; on iOS it is always true.
transitionEnd{ data: { closing: boolean } }

Event which fires when a transition animation ends.

transitionStart{ data: { closing: boolean } }

Event which fires when a transition animation starts.

NativeStackNavigationHelpers

Android
iOS
tvOS
Web

Type: NavigationHelpers<ParamListBase, NativeStackNavigationEventMap>

NativeStackNavigationOptions

Android
iOS
tvOS
Web
PropertyTypeDescription
animation(optional)ScreenProps[stackAnimation]

How the screen should animate when pushed or popped.

Supported values:

  • "default": use the platform default animation
  • "fade": fade screen in or out
  • "fade_from_bottom" – performs a fade from bottom animation
  • "flip": flip the screen, requires presentation: "modal" (iOS only)
  • "simple_push": use the platform default animation, but without shadow and native header transition (iOS only)
  • "slide_from_bottom": slide in the new screen from bottom
  • "slide_from_right": slide in the new screen from right (Android only, uses default animation on iOS)
  • "slide_from_left": slide in the new screen from left (Android only, uses default animation on iOS)
  • "ios_from_right" - iOS like slide in animation. pushes in the new screen from right to left (Android only, resolves to default transition on iOS)
  • "ios_from_left" - iOS like slide in animation. pushes in the new screen from left to right (Android only, resolves to default transition on iOS)
  • "none": don't animate the screen

Only supported on iOS and Android.

animationDuration(optional)number
Only for: 
iOS

Duration (in milliseconds) for the following transition animations on iOS:

  • slide_from_bottom
  • fade_from_bottom
  • fade
  • simple_push

Defaults to 500.

The duration is not customizable for:

  • Screens with default and flip animations
  • Screens with presentation set to modal, formSheet, pageSheet (regardless of animation)
animationMatchesGesture(optional)boolean
Only for: 
iOS

Whether the gesture to dismiss should use animation provided to animation prop. Defaults to false.

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 pop.

Supported values:

  • "push": the new screen will perform push animation.
  • "pop": the new screen will perform pop animation.

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 false.

contentStyle(optional)StyleProp<ViewStyle>

Style object for the scene content.

freezeOnBlur(optional)boolean

Whether inactive screens should be suspended from re-rendering. Defaults to false. Defaults to true when enableFreeze() is run at the top of the application. Requires react-native-screens version >=3.16.0.

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: false by default. If enabled, swipe gesture will use simple_push transition animation by default. It can be changed with animation & animationMatchesGesture props, but default iOS swipe animation is not achievable.

On iOS 26 and up: true by default to match new native behavior. You can still customize it with animation & animationMatchesGesture props.

Doesn't affect the behavior of screens presented modally.

fullScreenGestureShadowEnabled(optional)boolean

Deprecated: since iOS 26.

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 true.

This does not affect the behavior of transitions that don't use gestures, enabled by fullScreenGestureEnabled prop.

gestureDirection(optional)ScreenProps[swipeDirection]
Only for: 
iOS

Sets the direction in which you should swipe to dismiss the screen. When using vertical option, options fullScreenGestureEnabled: true, animationMatchesGesture: true and animation: 'slide_from_bottom' are set by default.

Supported values:

  • vertical – dismiss screen vertically
  • horizontal – dismiss screen horizontally (default)
gestureEnabled(optional)boolean
Only for: 
iOS

Whether you can use gestures to dismiss this screen. Defaults to true.

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 fullScreenGestureEnabled.

header(optional)(props: NativeStackHeaderProps) => React.ReactNode

Function that given HeaderProps returns a React Element to display as a header.

headerBackButtonDisplayMode(optional)ScreenStackHeaderConfigProps[backButtonDisplayMode]
Only for: 
iOS, web

How the back button displays icon and title.

Supported values:

  • "default" - Displays one of the following depending on the available space: previous screen's title, generic title (e.g. 'Back') or no title (only icon).
  • "generic" – Displays one of the following depending on the available space: generic title (e.g. 'Back') or no title (only icon).
  • "minimal" – Always displays only the icon without a title.

The space-aware behavior is disabled when:

  • The iOS version is 13 or lower
  • Custom font family or size is set (e.g. with headerBackTitleStyle)
  • Back button menu is disabled (e.g. with headerBackButtonMenuEnabled)

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 true. Requires react-native-screens version >=3.3.0.

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 headerTransparent to render content underneath a translucent header.

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

  • A chevron on iOS
  • An arrow on Android

Example

headerBackIcon: { type: 'image', source: require('./back-icon.png'), }
headerBackImageSource(optional)ImageSourcePropType

Deprecated: Use headerBackIcon instead.

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 headerBackButtonDisplayMode to read about limitations and interactions with other props. Use headerBackButtonDisplayMode: "minimal" to hide it.

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:

  • fontFamily
  • fontSize

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 headerLeft if you have specified it.

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 headerTransparent option needs to be set to true for this to work.

Note: Using both headerBlurEffect and scrollEdgeEffects (>= iOS 26) simultaneously may cause overlapping effects.

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 headerLargeTitle is true and the edge of any scrollable content reaches the matching edge of the header.

Supported properties:

  • backgroundColor

Only supported on iOS.

headerLargeTitle(optional)boolean

Deprecated: Use headerLargeTitleEnabled instead.

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 ScrollView or FlatList. If the scrollable area doesn't fill the screen, the large title won't collapse on scroll. You also need to specify contentInsetAdjustmentBehavior="automatic" in your ScrollView, FlatList etc.

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:

  • fontFamily
  • fontSize
  • fontWeight
  • color

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 headerBackVisible to show the back button along side left element. Will be overriden by headerLeftItems on iOS.

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 headerRightItems on iOS.

headerSearchBarOptions(optional)SearchBarProps

Options to render a native search bar. You also need to specify contentInsetAdjustmentBehavior="automatic" in your ScrollView, FlatList etc. If you don't have a ScrollView, specify headerTransparent: false.

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 false hides the header.

headerStyle(optional)StyleProp<{ backgroundColor: ColorValue }>

Style object for header. Supported properties:

  • backgroundColor
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 title or route name.

When a function is passed, it receives tintColor andchildren in the options object as an argument. The title string is passed in children.

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 left on platforms other than iOS.

Not supported on iOS. It's always center on iOS and cannot be changed.

headerTitleStyle(optional)StyleProp<Pick<TextStyle, 'fontFamily' | 'fontSize' | 'fontWeight'> & { color: ColorValue }>

Style object for header title. Supported properties:

  • fontFamily
  • fontSize
  • fontWeight
  • color
headerTransparent(optional)boolean

Boolean indicating whether the navigation bar is translucent. Setting this to true makes the header absolutely positioned, and changes the background color to transparent unless specified in headerStyle.

keyboardHandlingEnabled(optional)boolean
Only for: 
iOS

Whether the keyboard should hide when swiping to the previous screen. Defaults to false.

navigationBarColor(optional)ColorValue

Deprecated: For all apps targeting Android SDK 35 or above edge-to-edge is enabled by default. This prop is subject to removal in the future. See: https://developer.android.com/about/versions/15/behavior-changes-15#ux.

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 false.

navigationBarTranslucent(optional)boolean

Deprecated: For all apps targeting Android SDK 35 or above edge-to-edge is enabled by default. This prop is subject to removal in the future. See: https://developer.android.com/about/versions/15/behavior-changes-15#ux.

Android

Boolean indicating whether the content should be visible behind the navigation bar. Defaults to false.

orientation(optional)ScreenProps[screenOrientation]

The display orientation to use for the screen.

Supported values:

  • "default" - resolves to "all" without "portrait_down" on iOS. On Android, this lets the system decide the best orientation.
  • "all": all orientations are permitted.
  • "portrait": portrait orientations are permitted.
  • "portrait_up": right-side portrait orientation is permitted.
  • "portrait_down": upside-down portrait orientation is permitted.
  • "landscape": landscape orientations are permitted.
  • "landscape_left": landscape-left orientation is permitted.
  • "landscape_right": landscape-right orientation is permitted.

Only supported on iOS and Android.

presentation(optional)Exclude<ScreenProps[stackPresentation], 'push'> | 'card'

How should the screen be presented.

Supported values:

  • "card": the new screen will be pushed onto a stack, which means the default animation will be slide from the side on iOS, the animation on Android will vary depending on the OS version and theme.
  • "modal": the new screen will be presented modally. this also allows for a nested stack to be rendered inside the screen.
  • "transparentModal": the new screen will be presented modally, but in addition, the previous screen will stay so that the content below can still be seen if the screen has translucent background.
  • "containedModal": will use "UIModalPresentationCurrentContext" modal style on iOS and will fallback to "modal" on Android.
  • "containedTransparentModal": will use "UIModalPresentationOverCurrentContext" modal style on iOS and will fallback to "transparentModal" on Android.
  • "fullScreenModal": will use "UIModalPresentationFullScreen" modal style on iOS and will fallback to "modal" on Android.
  • "formSheet": will use "UIModalPresentationFormSheet" modal style on iOS and will fallback to "modal" on Android.
  • "pageSheet": will use "UIModalPresentationPageSheet" modal style on iOS and will fallback to "modal" on Android.

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 headerBlurEffect and scrollEdgeEffects (>= iOS 26) simultaneously may cause overlapping effects.

Edge effects can be configured for each edge separately. The following values are currently supported:

  • automatic - the automatic scroll edge effect style,
  • hard - a scroll edge effect with a hard cutoff and dividing line,
  • soft - a soft-edged scroll edge effect,
  • hidden - no scroll edge effect.

Defaults to automatic for each edge.

sheetAllowedDetents(optional)number[] | 'fitToContents'

Describes heights where a sheet can rest. Works only when presentation is set to formSheet.

Heights should be described as fraction (a number from [0, 1] interval) of screen height / maximum detent height. You can pass an array of ascending values each defining allowed sheet detent. iOS accepts any number of detents, while Android is limited to three.

There is also possibility to specify fitToContents literal, which intents to set the sheet height to the height of its contents.

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 [1.0].

sheetCornerRadius(optional)number

The corner radius that the sheet will try to render with. Works only when presentation is set to formSheet.

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 24.

sheetExpandsWhenScrolledToEdge(optional)boolean
Only for: 
iOS

Whether the sheet should expand to larger detent when scrolling. Works only when presentation is set to formSheet. Defaults to true.

sheetGrabberVisible(optional)boolean
Only for: 
iOS

Boolean indicating whether the sheet shows a grabber at the top. Works only when presentation is set to formSheet. Defaults to false.

sheetInitialDetentIndex(optional)number | 'last'

Index of the detent the sheet should expand to after being opened. Works only when stackPresentation is set to formSheet.

If the specified index is out of bounds of sheetAllowedDetents array, in dev environment more error will be thrown, in production the value will be reset to default value.

Additionaly there is last value available, when set the sheet will expand initially to last (largest) detent.

Defaults to 0 - which represents first detent in the detents array.

sheetLargestUndimmedDetentIndex(optional)number | 'none' | 'last'

The largest sheet detent for which a view underneath won't be dimmed. Works only when presentation is set to formSheet.

This prop can be set to an number, which indicates index of detent in sheetAllowedDetents array for which there won't be a dimming view beneath the sheet.

Additionaly there are following options available:

  • none - there will be dimming view for all detents levels,
  • last - there won't be a dimming view for any detent level.
sheetResizeAnimationEnabled(optional)boolean
Only for: 
Android

Whether the default native animation should be used when the sheet's with fitToContents content size changes.

When set to true, the sheet uses internal logic to synchronize size updates and translation animations during entry, exit, or content updates. This ensures a smooth transition for standard, static content mounting/unmounting.

When set to false, the internal animation and translation logic is ignored. This allows the sheet to adjust its size dynamically based on the current dimensions of the content provided by the developer, allowing implementing custom resizing animations.

Defaults to true.

sheetShouldOverflowTopInset(optional)boolean
Only for: 
Android

Whether the sheet content should be rendered behind the Status Bar or display cutouts.

When set to true, the sheet will extend to the physical edges of the stack, allowing content to be visible behind the status bar or display cutouts. Detent ratios in sheetAllowedDetents will be measured relative to the full stack height.

When set to false, the sheet's layout will be constrained by the inset from the top and the detent ratios will then be measured relative to the adjusted height (excluding the top inset). This means that sheetAllowedDetents will result in different sheet heights depending on this prop.

Defaults to false.

statusBarAnimation(optional)ScreenProps[statusBarAnimation]
Only for: 
android, iOS

Sets the status bar animation (similar to the StatusBar component). On Android, setting either fade or slide will set the transition of status bar color. On iOS, this option applies to appereance animation of the status bar. Requires setting View controller-based status bar appearance -> YES (or removing the config) in your Info.plist file.

Defaults to fade on iOS and none on Android.

Only supported on Android and iOS.

statusBarBackgroundColor(optional)ColorValue

Deprecated: For all apps targeting Android SDK 35 or above edge-to-edge is enabled by default. This prop is subject to removal in the future. See: https://developer.android.com/about/versions/15/behavior-changes-15#ux.

Android

Sets the status bar color (similar to the StatusBar component). Defaults to initial status bar color.

statusBarHidden(optional)boolean
Only for: 
android, iOS

Whether the status bar should be hidden on this screen. Requires setting View controller-based status bar appearance -> YES in your Info.plist file.

Only supported on Android and iOS.

statusBarStyle(optional)ScreenProps[statusBarStyle]
Only for: 
android, iOS

Sets the status bar color (similar to the StatusBar component). Requires setting View controller-based status bar appearance -> YES (or removing the config) in your Info.plist file. auto and inverted are supported only on iOS. On Android, they will fallback to light.

Defaults to auto on iOS and light on Android.

Only supported on Android and iOS.

statusBarTranslucent(optional)boolean

Deprecated: For all apps targeting Android SDK 35 or above edge-to-edge is enabled by default. This prop is subject to removal in the future. See: https://developer.android.com/about/versions/15/behavior-changes-15#ux.

Android

Sets the translucency of the status bar. Defaults to false.

title(optional)string

String that can be displayed in the header as a fallback for headerTitle.

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 headerLeft.

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 headerRight.

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.

NativeStackNavigationProp

Android
iOS
tvOS
Web

Literal Type: union

Acceptable values are: NavigationProp<ParamList, RouteName, NavigatorID, StackNavigationState<ParamList>, NativeStackNavigationOptions, NativeStackNavigationEventMap> | StackActionHelpers<ParamList>

NativeStackOptionsArgs

Android
iOS
tvOS
Web

Type: NativeStackScreenProps<ParamList, RouteName, NavigatorID> extended by:

PropertyTypeDescription
themeTheme
-
Android
iOS
tvOS
Web
PropertyTypeDescription
__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.

Android
iOS
tvOS
Web

Type: NavigationHelpers<ParamList> EventConsumer<NavigationContainerEventMap> extended by:

PropertyTypeDescription
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.

Android
iOS
tvOS
Web

Type: NavigationContainerRef<ParamList> extended by:

PropertyTypeDescription
currentNavigationContainerRef<ParamList> | null
-
Android
iOS
tvOS
Web

Literal Type: union

Acceptable values are: NavigationHelpersCommon<ParamList> | EventEmitter<EventMap> | NavigationHelpersRoute<ParamList, keyof ParamList>

Android
iOS
tvOS
Web

Type: Omit<NavigationHelpersCommon<ParamList, State>, 'getParent'> NavigationHelpersRoute<ParamList, RouteName> EventConsumer<EventMap & EventMapCore<State>> PrivateValueStore<[ParamList, RouteName, EventMap]> extended by:

PropertyTypeDescription
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.

Android
iOS
tvOS
Web

Type: object shaped as below:

PropertyTypeDescription
initial(optional)never
-
merge(optional)never
-
params(optional)never
-
path(optional)string
-
pop(optional)never
-
screen(optional)never
-
statePartialState<NavigationState> | NavigationState | undefined
-
Android
iOS
tvOS
Web
PropertyTypeDescription
EventMapEventMap
-
NavigationListNavigationList
-
NavigatorNavigator
-
NavigatorIDNavigatorID
-
ParamListParamList
-
ScreenOptionsScreenOptions
-
StateState
-
Android
iOS
tvOS
Web
PropertyTypeDescription
EventMapundefined
-
NavigationListNavigationListBase<ParamListBase>
-
NavigatorReact.ComponentType<any>
-
NavigatorIDstring | undefined
-
ParamListundefined
-
ScreenOptionsundefined
-
StateNavigationState
-

PathConfig

Android
iOS
tvOS
Web

Type: Partial<PathConfigAlias> extended by:

PropertyTypeDescription
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 String(value).

Example

stringify: { date: (value) => value.toISOString() }

PickPartial

Android
iOS
tvOS
Web

Literal Type: union

The list of input keys will become optional, everything else will remain the same.

Acceptable values are: Omit<T, K> | Partial<Pick<T, K>>

RedirectConfig

Android
iOS
tvOS
Web
PropertyTypeDescription
destinationstring
-
destinationContextKeystring
-
external(optional)boolean
-
methods(optional)string[]
-
permanent(optional)boolean
-
sourcestring
-

RelativePathString

Android
iOS
tvOS
Web

Literal Type: union

Acceptable values are: ./{string} | ../{string} | '..'

ResultState

Android
iOS
tvOS
Web

Type: PartialState<NavigationState> extended by:

PropertyTypeDescription
state(optional)ResultState
-

Route

Android
iOS
tvOS
Web

Type: Exclude<Extract[pathname], RelativePathString | ExternalPathString>

RouteConfig

Android
iOS
tvOS
Web

Literal Type: union

Acceptable values are: RouteConfigProps<ParamList, RouteName, State, ScreenOptions, EventMap, Navigation> | RouteConfigComponent<ParamList, RouteName>

RouteConfigComponent

Android
iOS
tvOS
Web

Type: object shaped as below:

PropertyTypeDescription
children(optional)never
-
componentScreenComponentType<ParamList, RouteName>

React component to render for this screen.

getComponent(optional)never
-

Or object shaped as below:

PropertyTypeDescription
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:

PropertyTypeDescription
children(props: { navigation: any, route: RouteProp<ParamList, RouteName> }) => React.ReactNode

Render callback to render content of this screen.

component(optional)never
-
getComponent(optional)never
-

RouteGroupConfig

Android
iOS
tvOS
Web
PropertyTypeDescription
childrenReact.ReactNode

Children React Elements to extract the route configuration from. Only Screen, Group and React.Fragment are supported as children.

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 screenLayout of parent group or navigator.

screenOptions(optional)ScreenOptions | (props: { navigation: Navigation, route: RouteProp<ParamList, keyof ParamList>, theme: ReactNavigation.Theme }) => ScreenOptions

Navigator options for this screen.

RouteProp

Android
iOS
tvOS
Web

Type: Route<Extract<RouteName, string>, ParamList[RouteName]>

Router

Android
iOS
tvOS
Web

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> ); }
PropertyTypeDescription
back() => void

Goes back in the navigation history.

canDismiss() => boolean

Checks if it is possible to dismiss the current screen. Returns true if the router is within the stack with more than one screen in stack's history.

canGoBack() => boolean

Navigates to a route in the navigator's history if it supports invoking the back function.

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 popToTop stack action.

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 href.

navigate(href: Href, options: NavigationOptions) => void

Navigates to the provided href.

prefetch(name: Href) => void

Prefetch a screen in the background before navigating to it

push(href: Href, options: NavigationOptions) => void

Navigates to the provided href using a push operation if possible.

replace(href: Href, options: NavigationOptions) => void

Navigates to route without appending to the history. Can be used with useFocusEffect to redirect imperatively to a new screen.

See: Using useRouter() hook to redirect.

setParams(params: Partial<RouteInputParams<T>>) => void

Updates the current route's query params.

ScreenLayoutArgs

Android
iOS
tvOS
Web
PropertyTypeDescription
childrenReact.ReactElement
-
navigationNavigation
-
optionsScreenOptions
-
routeRouteProp<ParamList, RouteName>
-
themeReactNavigation.Theme
-

ScreenListeners

Android
iOS
tvOS
Web

Type: Partial<undefined>

ScreenProps

Android
iOS
tvOS
Web
PropertyTypeDescription
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 redirect={true}, the layout will render null as there are no children to render.

SearchOrHash

Android
iOS
tvOS
Web

Literal Type: union

Acceptable values are: ?{string} | #{string}

ServerContainerRef

Android
iOS
tvOS
Web
PropertyTypeDescription
getCurrentOptions() => Record<string, any> | undefined
-

SingularOptions

Android
iOS
tvOS
Web

Type: boolean or object shaped as below:

(name, params) => string | undefined

ParameterTypeDescription
name(index signature)string
-
params(index signature)UnknownOutputParams
-

SitemapType

Android
iOS
tvOS
Web
PropertyTypeDescription
childrenSitemapType[]
-
contextKeystring
-
filenamestring
-
hrefstring | Href
-
isGeneratedboolean
-
isInitialboolean
-
isInternalboolean
-

Theme

Android
iOS
tvOS
Web

Type: NativeTheme

TypeBag

Android
iOS
tvOS
Web
PropertyTypeDescription
EventMapEventMap
-
NavigationListNavigationList
-
NavigatorNavigator
-
NavigatorIDNavigatorID
-
ParamListParamList
-
ScreenOptionsScreenOptions
-
StateState
-

TypedNavigator

Android
iOS
tvOS
Web

Literal Type: TypedNavigatorInternal

Acceptable values are: TypedNavigatorInternal<Bag[ParamList], Bag[NavigatorID], Bag[State], Bag[ScreenOptions], Bag[EventMap], Bag[NavigationList], Bag[Navigator]>