Expo UI and Router for iOS
Expo Router

Nesting navigators

Learn how to nest navigators in Expo Router.

Navigation UI elements (Link, Tabs, Stack) may move out of the Expo Router library in the future.

Using a Stack Navigator with Expo Router — Navigate between screens, pass params between screens, create dynamic routes, and configure the screen titles and animations.

Nesting navigators allow rendering a navigator inside the screen of another navigator. This guide is an extension of React Navigation: Nesting navigators to Expo Router. It provides an example of how nesting navigators work when using Expo Router.

Example

Consider the following file structure which is used as an example:

src

app

  _layout.tsx

  index.tsx

  home

   _layout.tsx

   feed.tsx

   messages.tsx

In the above example, src/app/home/feed.tsx matches /home/feed, and src/app/home/messages.tsx matches /home/messages.

import { Stack } from 'expo-router';

export default Stack;

Both src/app/home/_layout.tsx and src/app/index.tsx below are nested in the src/app/_layout.tsx layout so that it will be rendered as a stack.

import { Tabs } from 'expo-router';

export default Tabs;
import { Link } from 'expo-router';

export default function Root() {
  return <Link href="/home/messages">Navigate to nested route</Link>;
}

Both src/app/home/feed.tsx and src/app/home/messages.tsx below are nested in the home/_layout.tsx layout, so it will be rendered as a tab.

import { View, Text } from 'react-native';

export default function Feed() {
  return (
    <View>
      <Text>Feed screen</Text>
    </View>
  );
}
import { View, Text } from 'react-native';

export default function Messages() {
  return (
    <View>
      <Text>Messages screen</Text>
    </View>
  );
}

Stack inside native tabs

When using native tabs, you can nest a <Stack /> layout inside each tab to support headers and pushing screens. For a complete example, see Use Stacks inside tabs.

In React Navigation, navigating to a specific nested screen can be controlled by passing the screen name in params. This renders the specified nested screen instead of the initial screen for that nested navigator.

For example, from the initial screen inside the root navigator, you want to navigate to a screen called media inside settings (a nested navigator). In React Navigation, this is done as shown in the example below:

navigation.navigate('root', {
  screen: 'settings',
  params: {
    screen: 'media',
  },
});

In Expo Router, you can use router.push() to achieve the same result. There is no need to pass the screen name in the params explicitly.

router.push('/root/settings/media');

Sources

The original Expo docs for this page:

On this page