Problem
reactNavigationIntegration currently requires users to manually register the navigation container ref:
const ref = useRef(null);
<NavigationContainer
ref={ref}
onReady={() => navigationIntegration.registerNavigationContainer(ref)}
>
...
</NavigationContainer>
This boilerplate is repeated across every @react-navigation/native app and is a recurring source of misconfiguration in bug reports — when users forget the onReady call, navigation transactions never start and they see no spans / "Route Change" placeholders without realising why.
Proposal
Ship a thin wrapper component that renders <NavigationContainer> with the registration wired internally:
<Sentry.NavigationContainer>
...
</Sentry.NavigationContainer>
- Internally renders
<NavigationContainer ref={internalRef} onReady={...}> and calls navigationIntegration.registerNavigationContainer(internalRef) on ready.
- Forwards
ref (via forwardRef) so users keep imperative navigation (navigationRef.navigate(...)).
- Pass-through for all
<NavigationContainer> props.
- Resolves the active
reactNavigationIntegration from the current client; no-ops cleanly if it isn't registered.
What the current navigation auto-instrumentation covers
reactNavigationIntegration (@react-navigation/native and Expo Router; packages/core/src/js/tracing/reactnavigation.ts):
- User wires it up by calling registerNavigationContainer(ref) once after the container mounts (onReady for raw RN, useEffect for Expo Router).
- Listens to the container's unsafe_action (every dispatch) and state events to start/finish idle navigation spans.
- Names spans from the current route, with optional full-path naming across nested navigators (useFullPathsForNavigationRoutes) and span-name customization from dispatched action payloads (useDispatchedActionData).
- Extracts Expo-Router-style dynamic route params ([id], [...slug]) into span attributes, with non-structural query params filtered out for PII safety.
- Optional TTID start via enableTimeToInitialDisplay (with a fallback when the route doesn't render a component) and enableTimeToInitialDisplayForPreloadedRoutes.
- Optional prefetch span tracking (enablePrefetchTracking) when used with Sentry.wrapExpoRouter(useRouter()).
- Drops empty back-navigations (ignoreEmptyBackNavigationTransactions, default on) and route-change transactions that never produce a route.
- Re-registration is supported for Android Activity recreate; initial-state handling creates a span for the very first route even when Sentry.init runs before the container mounts, falling back to "Route Changed" if it doesn't.
reactNativeNavigationIntegration (Wix react-native-navigation; packages/core/src/js/tracing/reactnativenavigation.ts):
- Auto-wires by passing navigation: Navigation to the integration at Sentry.init — no per-container registration call.
- Starts navigation spans on componentDidAppear events from RNN.
Tied in but separate:
- Sentry.wrap(App) — App Start completion + touch event boundary; not navigation-specific.
- Sentry.wrapExpoRouter(useRouter()) — adds prefetch spans for Expo Router v5+; doesn't replace registerNavigationContainer.
References
https://docs.sentry.io/platforms/react-native/tracing/instrumentation/automatic-instrumentation/
https://docs.sentry.io/platforms/react-native/tracing/instrumentation/react-native-navigation/
Problem
reactNavigationIntegrationcurrently requires users to manually register the navigation container ref:This boilerplate is repeated across every
@react-navigation/nativeapp and is a recurring source of misconfiguration in bug reports — when users forget theonReadycall, navigation transactions never start and they see no spans / "Route Change" placeholders without realising why.Proposal
Ship a thin wrapper component that renders
<NavigationContainer>with the registration wired internally:<NavigationContainer ref={internalRef} onReady={...}>and callsnavigationIntegration.registerNavigationContainer(internalRef)on ready.ref(viaforwardRef) so users keep imperative navigation (navigationRef.navigate(...)).<NavigationContainer>props.reactNavigationIntegrationfrom the current client; no-ops cleanly if it isn't registered.What the current navigation auto-instrumentation covers
reactNavigationIntegration (@react-navigation/native and Expo Router; packages/core/src/js/tracing/reactnavigation.ts):
reactNativeNavigationIntegration (Wix react-native-navigation; packages/core/src/js/tracing/reactnativenavigation.ts):
Tied in but separate:
References
https://docs.sentry.io/platforms/react-native/tracing/instrumentation/automatic-instrumentation/
https://docs.sentry.io/platforms/react-native/tracing/instrumentation/react-native-navigation/