Skip to main content

Screen

Qualified layouts, like the ones found in expo-router (Stack, Tabs, Navigator) have a static Screen component which can be used to configure the behavior of a route declaratively.

All Screen components are the same and render null, but they have different types for convenience. The common props are:

  • name: string The name of the route to configure. This can only be used when the Screen is a child of a layout component.
  • redirect: true | string | undefined When true, redirects the request to the nearest sibling route in a layout. When a string matching the name of a sibling is used, the redirect will go to the provided sibling.
  • options: T | undefined The options to pass to the route. The type varies depending on the layout. Options can be used for Screen components rendered anywhere.

Dynamic options

In React Navigation, you often use screenOptions to configure layout options. In expo-router, you can use the <Screen /> component from any built-in layout to configure the nearest layout.

Consider the following stack layout:

app/_layout.tsx
import { Stack } from "expo-router";

export default function Layout() {
return <Stack />;
}

We can configure the title of the stack per-screen using the <Stack.Screen /> component:

app/index.tsx
import { View } from "react-native";
import { Stack } from "expo-router";

export default function Home() {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Stack.Screen options={{ title: "Overview" }} />
</View>
);
}

The options are the same as the screenOptions prop in React Navigation.

Static options

Sometimes you want static options to live outside the route component, this is useful for things like tabs or drawer items which should be configured before the route loads. You can use the <Screen /> option directly in the layout component with the name prop set to the route name (file name without the extension):

app/_layout.tsx
import { Tabs } from "expo-router";

export default function Layout() {
return (
<Tabs>
<Tabs.Screen name="index" options={{ title: "Overview" }} />
</Tabs>
);
}

You can use this system to the order of screens and tabs in a layout. For example, if you want to change the order of screens in a stack, you can use the name prop to specify the order:

app/_layout.tsx
import { Tabs } from "expo-router";

export default function Layout() {
return (
<Tabs>
{/* The screens will now show up from left to right: index, settings, all other routes... */}
<Tabs.Screen name="index" />
<Tabs.Screen name="settings" />
</Tabs>
);
}

You can also use a relative path as the name prop to access a parent layout's options:

app/tabs/page.tsx
import { Stack, Tabs } from "expo-router";

export default function Page() {
return (
<>
<Stack.Screen name="../../" options={{ ... }} />
<Tabs.Screen name="/_layout.js" options={{ ... }} />
</>
);
}

Props

Migrate the following props from React Navigation Screen:

component

Expo Router automatically sets the component based on the file convention. This prop is not used.

children

Expo Router does not support the children prop. Use query parameters and React Context to pass data to the route component.

name

This is similar to the name prop in React Navigation, but it can only be used when the Screen is a child of a layout component. The name can also be used with a relative path to access a parent layout's options when not used as the child of a layout.

getId

By default, Expo Router automatically generates the ID based on the query parameters of a dynamic route. This value can be customized by using as-is in Expo Router.