📄 expo/versions/v54.0.0/sdk/router-ui

File: router-ui.md | Updated: 11/15/2025

Source: https://docs.expo.dev/versions/v54.0.0/sdk/router-ui

Hide navigation

Search

Ctrl K

Home Guides EAS Reference Learn

Reference version

SDK 54

Archive Expo Snack Discord and Forums Newsletter

Expo Router UI

GitHub Changelog npm

An Expo Router submodule that provides headless tab components to create custom tab layouts.

GitHub Changelog npm

Android

iOS

tvOS

Web

Bundled version:

~6.0.14

Copy page


expo-router/ui is a submodule of expo-router library and exports components and hooks to build custom tab layouts, rather than using the default React Navigation navigators provided by expo-router.

See the Expo Router reference for more information about the file-based routing library for native and web app.

Installation


To use expo-router/ui in your project, you need to install expo-router in your project. 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

Copy

{ "expo": { "plugins": ["expo-router"] } }

Usage


For information about using expo-router/ui in Custom tab layouts guide:

Custom tab layouts

API


import { Tabs, TabList, TabTrigger, TabSlot } from 'expo-router/ui';

Components


TabContext

Type: React.[Element](https://www.typescriptlang.org/docs/handbook/jsx.html#function-component) <[ProviderProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#providerprops) <[ExpoTabsNavigatorScreenOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#expotabsnavigatorscreenoptions) >>

TabList

Type: React.[Element](https://www.typescriptlang.org/docs/handbook/jsx.html#function-component) <[TabListProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tablistprops) >

Wrapper component for TabTriggers. TabTriggers within the TabList define the tabs.

Example

<Tabs> <TabSlot /> <TabList> <TabTrigger name="home" href="/" /> </TabList> </Tabs>

TabListProps

asChild

Optional • Type: boolean

Forward props to child component and removes the extra <View>. Useful for custom wrappers.

Inherited Props

  • [ViewProps](https://reactnative.dev/docs/view#props)

Tabs

Type: React.[Element](https://www.typescriptlang.org/docs/handbook/jsx.html#function-component) <[TabsProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabsprops) >

Root component for the headless tabs.

See: useTabsWithChildren for a hook version of this component.

Example

<Tabs> <TabSlot /> <TabList> <TabTrigger name="home" href="/" /> </TabList> </Tabs>

TabsProps

asChild

Optional • Type: boolean

Forward props to child component and removes the extra <View>. Useful for custom wrappers.

options

Optional • Type: [UseTabsOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#usetabsoptions)

Inherited Props

  • [ViewProps](https://reactnative.dev/docs/view#props)

TabSlot

Type: React.[Element](https://www.typescriptlang.org/docs/handbook/jsx.html#function-component) <[TabSlotProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabslotprops) >

Renders the current tab.

See: useTabSlot for a hook version of this component.

Example

<Tabs> <TabSlot /> <TabList> <TabTrigger name="home" href="/" /> </TabList> </Tabs>

TabSlotProps

detachInactiveScreens

Optional • Type: boolean

Remove inactive screens.

renderFn

Optional • Type: defaultTabsSlotRender

Override how the Screen component is rendered.

Inherited Props

  • ComponentProps<ScreenContainer>

TabTrigger

Type: React.[Element](https://www.typescriptlang.org/docs/handbook/jsx.html#function-component) <[TabTriggerProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabtriggerprops) >

Creates a trigger to navigate to a tab. When used as child of TabList, its functionality slightly changes since the href prop is required, and the trigger also defines what routes are present in the Tabs.

When used outside of TabList, this component no longer requires an href.

Example

<Tabs> <TabSlot /> <TabList> <TabTrigger name="home" href="/" /> </TabList> </Tabs>

TabTriggerProps

asChild

Optional • Type: boolean

Forward props to child component. Useful for custom wrappers.

href

Optional • Type: [Href](https://docs.expo.dev/versions/v54.0.0/sdk/router#href-1)

Name of tab. Required when used within a TabList.

name

Type: string

Name of tab. When used within a TabList this sets the name of the tab. Otherwise, this references the name.

reset

Optional • Literal type: union

Resets the route when switching to a tab.

Acceptable values are: SwitchToOptions[reset] | 'onLongPress'

Inherited Props

  • [PressablePropsWithoutFunctionChildren](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#pressablepropswithoutfunctionchildren)

useTabSlot

Type: React.[Element](https://www.typescriptlang.org/docs/handbook/jsx.html#function-component) <[TabSlotProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabslotprops) >

Returns a ReactElement of the current tab.

Example

function MyTabSlot() { const slot = useTabSlot(); return slot; }

Hooks


useTabSlot(namedParameters)

| Parameter | Type | | --- | --- | | namedParameters(optional) | [TabSlotProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabslotprops) |

Returns a ReactElement of the current tab.

Returns:

[Element](https://www.typescriptlang.org/docs/handbook/jsx.html#function-component)

Example

function MyTabSlot() { const slot = useTabSlot(); return slot; }

useTabsWithChildren(options)

| Parameter | Type | | --- | --- | | options | [UseTabsWithChildrenOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#usetabswithchildrenoptions) |

Hook version of Tabs. The returned NavigationContent component should be rendered. Using the hook requires using the <TabList /> and <TabTrigger /> components exported from Expo Router.

The useTabsWithTriggers() hook can be used for custom components.

See: Tabs for the component version of this hook.

Example

export function MyTabs({ children }) { const { NavigationContent } = useTabsWithChildren({ children }) return <NavigationContent /> }

useTabsWithTriggers(options)

| Parameter | Type | | --- | --- | | options | [UseTabsWithTriggersOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#usetabswithtriggersoptions) |

Alternative hook version of Tabs that uses explicit triggers instead of children.

Returns:

[TabsContextValue](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabscontextvalue)

See: Tabs for the component version of this hook.

Example

export function MyTabs({ children }) { const { NavigationContent } = useTabsWithChildren({ triggers: [] }) return <NavigationContent /> }

useTabTrigger(options)

| Parameter | Type | | --- | --- | | options | [TabTriggerProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabtriggerprops) |

Utility hook creating custom TabTrigger.

Returns:

[UseTabTriggerResult](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#usetabtriggerresult)

Types


ExpoTabsNavigationProp

Type: [NavigationProp](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#navigationprop) <ParamList, [RouteName](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#routename) , [NavigatorID](https://reactnavigation.org/docs/custom-navigators/#type-checking-navigators) , [TabNavigationState](https://reactnavigation.org/docs/custom-navigators/#type-checking-navigators) <ParamListBase>, [ExpoTabsScreenOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#expotabsscreenoptions) , [TabNavigationEventMap](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabnavigationeventmap) >

ExpoTabsNavigatorOptions

Literal Type: union

Acceptable values are: [DefaultNavigatorOptions](https://reactnavigation.org/docs/custom-navigators/#type-checking-navigators) <ParamListBase, string | undefined, [TabNavigationState](https://reactnavigation.org/docs/custom-navigators/#type-checking-navigators) <ParamListBase>, [ExpoTabsScreenOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#expotabsscreenoptions) , [TabNavigationEventMap](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabnavigationeventmap) , [ExpoTabsNavigationProp](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#expotabsnavigationprop) <ParamListBase>> | [Omit](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) <[TabRouterOptions](https://reactnavigation.org/docs/custom-navigators/#type-checking-navigators) , 'initialRouteName'> | [ExpoTabsNavigatorScreenOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#expotabsnavigatorscreenoptions)

ExpoTabsNavigatorScreenOptions

| Property | Type | Description | | --- | --- | --- | | detachInactiveScreens(optional) | boolean | - | | freezeOnBlur(optional) | boolean | - | | lazy(optional) | boolean | - | | unmountOnBlur(optional) | boolean | - |

ExpoTabsResetValue

Literal Type: string

Acceptable values are: 'always' | 'onFocus' | 'never'

ExpoTabsScreenOptions

Type: [Pick](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys) <[BottomTabNavigationOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#bottomtabnavigationoptions) , 'title' | 'lazy' | 'freezeOnBlur'> extended by:

| Property | Type | Description | | --- | --- | --- | | action | [NavigationAction](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#navigationaction) | - | | params(optional) | object | - | | title | string | - |

SwitchToOptions

Options for switchTab function.

| Property | Type | Description | | --- | --- | --- | | reset(optional) | [ExpoTabsResetValue](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#expotabsresetvalue) | Navigate and reset the history. |

TabNavigationEventMap

| Property | Type | Description | | --- | --- | --- | | tabLongPress | { data: undefined } | Event which fires on long press on the tab in the tab bar. | | tabPress | { canPreventDefault: true, data: undefined } | Event which fires on tapping on the tab in the tab bar. |

TabsContextValue

Type: [ReturnType](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#returntype) <useNavigationBuilder>

The React Navigation custom navigator.

See: useNavigationBuilder hook from React Navigation for more information.

TabsSlotRenderOptions

Options provided to the UseTabSlotOptions.

| Property | Type | Description | | --- | --- | --- | | detachInactiveScreens | boolean | Should the screen be unloaded when inactive. | | index | number | Index of screen. | | isFocused | boolean | Whether the screen is focused. | | loaded | boolean | Whether the screen has been loaded. |

TabTriggerOptions

| Property | Type | Description | | --- | --- | --- | | href | [Href](https://docs.expo.dev/versions/v54.0.0/sdk/router#href-1) | - | | name | string | - |

Trigger

Type: extended by:

| Property | Type | Description | | --- | --- | --- | | isFocused | boolean | - | | resolvedHref | string | - | | route | [number] | - |

UseTabsOptions

Options to provide to the Tab Router.

Type: [Omit](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) <[DefaultNavigatorOptions](https://reactnavigation.org/docs/custom-navigators/#type-checking-navigators) <ParamListBase, any, [TabNavigationState](https://reactnavigation.org/docs/custom-navigators/#type-checking-navigators) <any>, [ExpoTabsScreenOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#expotabsscreenoptions) , [TabNavigationEventMap](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#tabnavigationeventmap) , any>, 'children'> extended by:

| Property | Type | Description | | --- | --- | --- | | backBehavior(optional) | TabRouterOptions[backBehavior] | - |

UseTabsWithChildrenOptions

Type: PropsWithChildren<[UseTabsOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#usetabsoptions) >

UseTabsWithTriggersOptions

Type: [UseTabsOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#usetabsoptions) extended by:

| Property | Type | Description | | --- | --- | --- | | triggers | [ScreenTrigger[]](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#screentrigger) | - |

UseTabTriggerResult

| Property | Type | Description | | --- | --- | --- | | getTrigger | (name: string) => [Trigger](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#trigger) \| undefined | - | | switchTab | (name: string, options: [SwitchToOptions](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#switchtooptions) ) => void | - | | trigger(optional) | [Trigger](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#trigger) | - | | triggerProps | [TriggerProps](https://docs.expo.dev/versions/v54.0.0/sdk/router-ui#triggerprops) | - |