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
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 );
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 >
);
}
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:
Blank Stack (Recommended)
import {
createBlankStackNavigator ,
type BlankStackNavigationOptions ,
} from "react-native-screen-transitions/blank-stack" ;
const { Navigator } = createBlankStackNavigator ();
export const Stack = withLayoutContext <
BlankStackNavigationOptions ,
typeof Navigator
> ( Navigator );
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.