This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

Prevent screen removal

Edit page

Learn how to confirm navigation before Expo Router removes a screen.


Use usePreventRemove() to keep a screen open while it contains unsaved changes. The hook runs your callback when navigation tries to remove the screen.

src/app/edit-profile.tsx
import { usePreventRemove } from 'expo-router'; import { useState } from 'react'; import { Alert, Platform, TextInput } from 'react-native'; export default function EditProfile() { const [name, setName] = useState(''); const hasUnsavedChanges = name.length > 0; usePreventRemove(hasUnsavedChanges, ({ repeat }) => { const discardChanges = () => { setName(''); repeat(); }; if (Platform.OS === 'web') { if (window.confirm('Discard your unsaved changes?')) { discardChanges(); } return; } Alert.alert('Discard changes?', 'You have unsaved changes.', [ { text: 'Keep editing', style: 'cancel' }, { text: 'Discard', style: 'destructive', onPress: discardChanges, }, ]); }); return <TextInput value={name} onChangeText={setName} placeholder="Name" />; }

Set the value passed to usePreventRemove() to false before calling repeat(). This keeps your state synchronized with removal prevention.

Disable removal prevention

The hook also returns a function that disables prevention. Use it when you want to cancel the blocked action and navigate somewhere else.

src/app/edit-profile.tsx
import { router, usePreventRemove } from 'expo-router'; import { useState } from 'react'; import { Button } from 'react-native'; export default function EditProfile() { const [hasUnsavedChanges, setHasUnsavedChanges] = useState(true); const disablePrevention = usePreventRemove(hasUnsavedChanges); function leaveForm() { setHasUnsavedChanges(false); disablePrevention(); router.replace('/profile'); } return <Button title="Leave without saving" onPress={leaveForm} />; }

See the Expo Router API reference for all removal prevention options.