Skip to main content

Overview

Expo Router provides a file-based routing system for React Native apps. You can integrate react-native-screen-transitions with Expo Router using the withLayoutContext helper to create custom stack navigators.

Setup

1

Create a custom Stack component

Use withLayoutContext to wrap the navigator from createBlankStackNavigator:
import { withLayoutContext } from "expo-router";
import {
  createBlankStackNavigator,
  type BlankStackNavigationOptions,
} from "react-native-screen-transitions/blank-stack";

const { Navigator } = createBlankStackNavigator();

export const Stack = withLayoutContext<
  BlankStackNavigationOptions,
  typeof Navigator
>(Navigator);
2

Use the Stack in your layout

Import and use your custom Stack component in _layout.tsx:
// app/_layout.tsx
import Transition from "react-native-screen-transitions";
import { Stack } from "./stack";

export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="index" />
      <Stack.Screen
        name="details"
        options={{
          ...Transition.Presets.SlideFromBottom(),
        }}
      />
    </Stack>
  );
}
3

Navigate using Expo Router

Use Expo Router’s navigation API in your screens:
import { router } from "expo-router";
import { Button } from "react-native";

export default function HomeScreen() {
  return (
    <Button
      title="Go to Details"
      onPress={() => router.push("/details")}
    />
  );
}

Dynamic Options with Route Params

You can use route parameters to configure transitions dynamically:
// app/_layout.tsx
import Transition from "react-native-screen-transitions";
import { Stack } from "./stack";

export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="index" />
      <Stack.Screen
        name="details"
        options={({ route }) => ({
          ...Transition.Presets.SharedAppleMusic({
            sharedBoundTag: route.params?.sharedBoundTag ?? "",
          }),
        })}
      />
    </Stack>
  );
}
// app/index.tsx
import { router } from "expo-router";
import Transition from "react-native-screen-transitions";

export default function HomeScreen() {
  return (
    <Transition.Pressable
      sharedBoundTag="album-art"
      onPress={() => {
        router.push({
          pathname: "/details",
          params: { sharedBoundTag: "album-art" },
        });
      }}
    >
      {/* Your content */}
    </Transition.Pressable>
  );
}
The withLayoutContext helper works with all stack types: Blank Stack, Native Stack, and Component Stack.

Stack Type Compatibility

All three stack types work with Expo Router:
import {
  createNativeStackNavigator,
  type NativeStackNavigationOptions,
} from "react-native-screen-transitions/native-stack";

const { Navigator } = createNativeStackNavigator();

export const Stack = withLayoutContext<
  NativeStackNavigationOptions,
  typeof Navigator
>(Navigator);
Remember to enable transitions in your screen options:
<Stack.Screen
  name="details"
  options={{
    enableTransitions: true,
    ...Transition.Presets.SlideFromBottom(),
  }}
/>
Component Stack is experimental and doesn’t integrate with React Navigation’s routing system. It’s not recommended for use with Expo Router.