Skip to main content

Custom navigators

You can create your own custom navigators with the Navigator component.

API

The Navigator component wraps the useNavigationBuilder hook from React Navigation.

The return value of useNavigationBuilder can be accessed with the Navigator.useContext() hook from inside the <Navigator /> component. Properties can be passed to useNavigationBuilder using the props of the <Navigator /> component, this includes initialRouteName, screenOptions, router.

All of the children of a <Navigator /> component will be rendered as-is.

  • Navigator.useContext: Access the React Navigation state, navigation, descriptors, and router for the custom navigator.
  • Navigator.Slot: A React component used to render the currently selected route. This component can only be rendered inside a <Navigator /> component.

Example

Custom layouts have an internal context that is ignored when using the <Slot /> component without a <Navigator /> component wrapping it.

import { View } from "react-native";
import { TabRouter } from "@react-navigation/native";

import { Navigator, usePathname, Slot, Link } from "expo-router";

export default function App() {
return (
<Navigator router={TabRouter}>
<Header />
<Slot />
</Navigator>
);
}

function Header() {
const { navigation, state, descriptors, router } = Navigator.useContext();

const pathname = usePathname();

return (
<View>
<Link href="/">Home</Link>
<Link
href="/profile"
// Use `pathname` to determine if the link is active.
style={[pathname === "/profile" && { color: "blue" }]}
>
Profile
</Link>
<Link href="/settings">Settings</Link>
</View>
);
}

In expo-router, you currently need all layout routes to be a navigator. This is because we don't have a way to render a route without a parent navigator.