This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 51).
A file-based routing library for React Native and web applications.
GitHub
npm
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.
-Â
npx expo install expo-router
If you are using the default template to create a new project, expo-router
config plugin is configured in the app config automatically.
{
"expo": {
"plugins": ["expo-router"]
}
}
Find more information and guides about using expo-router
in Expo Router section.
import { Stack, Tabs, Link } from 'expo-router';
Link
Type: React.Element<PropsWithChildren<LinkProps<T>>>
Component to render link to another route using a path. Uses an anchor tag on the web.
asChild
Optional • Type: boolean
Forward props to child component. Useful for custom buttons.
className
Optional • Type: string
On web, this sets the HTML class
directly. On native, this can be used with CSS interop tools like Nativewind.
onPress
Optional • Type: (e: MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void
This function is called on press. Text intrinsically supports press handling with a default highlight state (which can be disabled with suppressHighlighting).
relativeToDirectory
Optional • Type: boolean
Relative URL references are either relative to the directory or the document. By default, relative paths are relative to the document.
replace
Optional • Type: boolean
Should replace the current route without adding to the history.
Omit<TextProps, 'href'>
WebAnchorProps
Slot
Type: React.Element<Omit<NavigatorProps<any>, 'children'>>
Renders the currently selected content.
There are actually two different implementations of Slot:
As a custom <Navigator /> will set the NavigatorContext.contextKey to be the current _layout, we can use this to determine if we are inside a custom navigator or not.
useFocusEffect(effect, do_not_pass_a_second_prop)
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.
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')
}, []);
);
return </>;
}
useGlobalSearchParams()
Get the globally selected query parameters, including dynamic path segments. This function will update even when the route is not focused. Useful for analytics or other background operations that don't draw to the screen.
When querying search params in a stack, opt-towards using useLocalSearchParams
as these will only update when the route is focused.
Route URL example: acme://profile/baconbrix?extra=info
.
Note: See local versus global search parameters for usage information.
RouteParams<TRoute, TParams>
Example
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>;
}
useLocalSearchParams()
Returns the URL parameters for the contextually focused route. e.g. /acme?foo=bar
-> { foo: "bar" }
.
This is 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.
To observe updates even when the invoking route is not focused, use useGlobalSearchParams()
.
RouteParams<TRoute, TParams>
useNavigation(parent)
Parameter | Type | Description |
---|---|---|
parent (optional) | string | Provide an absolute path such as |
Access the underlying React Navigation navigation
prop to imperatively access layout-specific functionality like navigation.openDrawer()
in a Drawer layout.
T
The navigation object for the current route.
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.
See React Navigation documentation on navigation dependent functions for more information.
useNavigationContainerRef()
NavigationContainerRefWithCurrent<RootParamList>
The root <NavigationContainer />
ref for the app. The ref.current
may be null
if the <NavigationContainer />
hasn't mounted yet.
usePathname()
Global selected route location without search parameters. For example, /acme?foo=bar
-> /acme
. Segments will be normalized: /[id]?id=normal
-> /normal
.
string
Example
import { Text } from 'react-native';
import { useSegments } from 'expo-router';
export default function Route() {
// segments = ["profile", "[user]"]</b>
const segments = useSegments();
return <Text>Hello</Text>;
}
Deprecated Use
useNavigationContainerRef
instead, which returns a Reactref
.
useRootNavigation()
null | NavigationContainerRef<RootParamList>
useSegments()
Get 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 -> ["[id]"]
.
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, and strictly typed useSegments
function:
- app
- [user]
- index.js
- followers.js
- settings.js
This can be strictly typed using the following abstract:
const [first, second] = useSegments<['settings'] | ['[user]'] | ['[user]', 'followers']>()
Redirect(namedParameters)
Parameter | Type |
---|---|
namedParameters | {
href: Href
} |
Redirects to the href as soon as the component is mounted.
null
withLayoutContext(Nav, processor)
Parameter | Type |
---|---|
Nav | T |
processor (optional) | (options: ScreenProps[]) => ScreenProps[] |
Return a navigator that automatically injects matched routes and renders nothing when there are no children. Return type with children prop optional
Component<PropsWithoutRef<PickPartial<ComponentProps<T>, 'children'>>> & {
Screen: (props: ScreenProps<TOptions, TState, TEventMap>) => null
}
EffectCallback()
Memoized callback containing the effect, should optionally return a cleanup function.
Href
Type: GeneratedHref<T>
The main routing type for Expo Router. Includes all available routes with strongly typed parameters.
A Href can either be a string or an object.
Href accepts an optional T parameter to correctly type dynamic routes string.
For example: Without the generic the route /folder/[slug]
will be typed as /folder/${string}
,
which is incorrect as /folder/apple/orange
would be valid. But by passing desired route as a generic Href<'/folder/apple'>
,
it will validate against this edge case.
NativeIntent
Name | Type | Description |
---|---|---|
legacy_subscribe (optional) | (listener: (url: string) => void) => undefined | void | () => void | - |
redirectSystemPath (optional) | (event: {
initial: boolean,
path: string
}) => Promise<string> | string | - |
PickPartial
Literal Type: multiple types
The list of input keys will become optional, everything else will remain the same.
ResultState
Type: PartialState<NavigationState>
extended by:
Name | Type | Description |
---|---|---|
state (optional) | ResultState | - |
Router
Name | Type | Description |
---|---|---|
back | () => void | Go back in the history. |
canDismiss | () => boolean | If there's history that supports invoking the |
canGoBack | () => boolean | If there's history that supports invoking the |
dismiss | (count: number) => void | Navigate to a screen with a stack lower than the current screen. Using the provided count if possible, otherwise 1. |
dismissAll | () => void | Navigate to first screen within the lowest stack. |
navigate | (href: Href<T>, options: NavigationOptions) => void | Navigate to the provided href. |
push | (href: Href<T>, options: NavigationOptions) => void | Navigate to the provided href using a push operation if possible. |
replace | (href: Href<T>, options: NavigationOptions) => void | Navigate to route without appending to the history. |
setParams | (params: Partial<RouteParamInput<T>>) => void | Update the current route query params. |
ScreenProps
Name | Type | Description |
---|---|---|
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 |
WebAnchorProps
Name | Type | Description |
---|---|---|
download (optional) | string | Specifies that the The value of the Example
|
rel (optional) | string | Specifies the relationship between the Common values:
The This property is passed to the underlying anchor ( Example
|
target (optional) | '_self' | '_blank' | '_parent' | '_top' | string & object | Specifies where to open the
This property is passed to the underlying anchor ( Default: '_self' Example
|