NativeKeel ยท React Native fixes

Expo Router SDK 58: initialRouteName, freezeOnBlur and beforeRemove

Updated 2026-10-23

Expo SDK 58 reworked the navigation core of Expo Router: "navigation state is deterministic and easier to reason about", and the router "no longer carries most of the forked React Navigation API". The release notes say most apps won't notice. The ones that do usually hit one of the changes below, and none of them shows an error: the old option is simply ignored.

initialRouteName is removed, both in unstable_settings and as a prop on a layout's navigator. It was in Expo's own app template (export const unstable_settings = { initialRouteName: '(tabs)' }), so many apps have it. Replace it with an anchor, which adds a back destination below a deep-linked screen:

- export const unstable_settings = { initialRouteName: '(tabs)' };
+ export const unstable_settings = { anchor: '(tabs)' };

- return <Stack initialRouteName="index" />;
+ return <Stack />;

Do not use the anchor to choose the first screen: the launch URL decides that. When you navigate in code and want the anchor inserted below the destination, pass { withAnchor: true }.

beforeRemove is removed. A listener on it (the usual "discard unsaved changes?" prompt) no longer fires, so the user leaves without being asked. Use usePreventRemove from expo-router; its callback receives repeat, which continues the navigation that was blocked:

import { usePreventRemove } from 'expo-router';

usePreventRemove(hasUnsavedChanges, ({ repeat }) => {
  confirmDiscard(() => {
    setHasUnsavedChanges(false);
    repeat();
  });
});

To navigate somewhere else instead, keep the disablePrevention function the hook returns: set the condition to false, call disablePrevention(), then navigate.

freezeOnBlur has no effect. Screens are no longer frozen in the background. Use activityEnabled on the navigator or a screen (true, or a number that sets the threshold on stacks), or wrap part of a screen in NavigationAwareActivity.

Layout Screen props redirect, initialParams and navigationKey are removed. Use a Redirect route, or Stack.Protected with redirectTo, and default values inside the screen instead of initialParams.

Also in the guide: nested navigation with navigate('(tabs)', { screen: 'feed', params }) no longer works (navigate to a complete href with useRouter().push({ pathname, params })), parent route params are no longer copied into child routes, useNavigation throws outside a navigator, and tabs and drawers only show screens declared in the layout (options={{ href: null }} hides a route). Imports from expo-router/react-navigation lost many exports; the guide has a table with the replacement for each.

Check before you upgrade. npx nativekeel upgrade lists each of these with file and line when your app uses Expo Router below SDK 58. In our scan of 401 open-source apps that use Expo Router below SDK 58, 78 still set initialRouteName, 16 listen to beforeRemove and 16 use freezeOnBlur.

Check your whole app in one command: npx nativekeel
Free, runs locally (your code is not uploaded), no account. It reports this along with the other upgrade, store, crash and security problems it checks for.
Rather hand the upgrade over? The engineer behind NativeKeel takes on a few upgrades at a time: send your report to hello@nativekeel.com for a fixed quote.

Sources