Skip to main content

Track Navigation

This package collect telemetry around Navigation based on expo-router, @react-navigation/native and react-native-navigation.

Adding Context to Sessions

Embrace can collect basic session data and crashes as you've already seen in the Crash Reporting and Session Reporting sections. Embrace can also collect the screens that your app opened and include it as context within your sessions. Here's how you add the screen tracker to the session.

Install the Package

npm:

npm install @embrace-io/react-native-navigation

yarn:

yarn add @embrace-io/react-native-navigation

Setup in your code

import React from "react";
import {useEmbraceNativeTracerProvider} from "@embrace-io/react-native-tracer-provider";
import {EmbraceNavigationTracker} from "@embrace-io/react-native-navigation";
import {useNavigationContainerRef} from "expo-router";
import {useEmbrace} from "@embrace-io/react-native";

const App = () => {
const {isPending, isStarted} = useEmbrace({
ios: {
appId: "__APP_ID__",
},
});

// make sure a tracer provider is registered BEFORE you attempt to record the first span (otherwise somo initial telemetrt can be missed).
const {tracerProvider, isLoading: isLoadingTracerProvider} =
useEmbraceNativeTracerProvider({}, isStarted);

const expoNavigationRef = useNavigationContainerRef();

if (isLoadingTracerProvider) {
return (
<View>
<Text>Loading Tracer Provider...</Text>
</View>
);
}

return (
<EmbraceNavigationTracker
ref={expoNavigationRef}
tracerProvider={tracerProvider}
// These static attributes will be passed into each created span
screenAttributes={{
"static.attribute": 123456,
"custom.key": "custom.value",
}}>
{/* rest of the navigation */}
</EmbraceNavigationTracker>
);
};

export default App;

Disable Auto Tracking for Native Screens

Embrace automatically collects the native screens, if you do not want to see them in the session you can disable it.

Go to your embrace-config.json inside android/app/src/main and edit the sdk_config, your file should be like this

{
"app_id": "__APP_ID__",
"api_token": "__API_TOKEN__",
"sdk_config": {
"app_framework": "react_native",
// Add these lines
"view_config": {
"enable_automatic_activity_capture": false
}
}
}

If instead you only initialized the SDK through JavaScript then the disableAutomaticViewCapture property can be set during the call to initialize the SDK:

const App = () => {
const {isPending, isStarted} = useEmbrace({
ios: {
appId: "__APP_ID__",
disableAutomaticViewCapture: true, // disabling the feature
},
});

if (isPending) {
return (
<View>
<Text>Loading Embrace</Text>
</View>
);
} else {
if (!isStarted) {
console.log("An error occurred during Embrace initialization");
}
}

return (
/* regular content of the application */
)
};

export default App;

Migrating from older versions

The old @embrace-io/react-navigation exposed a hook that receives a reference pointing to the NavigationContainer component:

import {useRef} from 'react'
import {useEmbraceNavigationTracker} from '@embrace-io/react-navigation';

function App() {
// Create the reference
const navigationRef = useRef();
// Pass the reference to Embrace's Hook
useEmbraceNavigationTracker(navigationRef);

return (
// Assign the NavigationContainer reference value to the useRef created
<NavigationContainer ref={navigationRef}>
<Screens... />
</NavigationContainer>
);
}

Now you just need to pass the reference into the new EmbraceNavigationTracker component exposed by the newest version of @embrace-io/react-native-navigation and configure it in the desired way:

import React, {useRef} from "react";
import {EmbraceNativeNavigationTracker} from "@embrace-io/react-native-navigation";
import {useEmbraceNativeTracerProvider} from "@embrace-io/react-native-tracer-provider";
import {
NavigationContainer,
useNavigationContainerRef,
} from "@react-navigation/native";

function App() {
// Embrace initialization should happen before

// as of now if you inspect the source code of `useNavigationContainerRef` from `@react-navigation/native` you will see that it returns `navigation.current` instead of the entire shape of a reference
const navigationRefVal = useNavigationContainerRef();
// We need here the entire shape, so we re-create it and pass it down into the `ref` prop for the `EmbraceNavigationTracker` component.
const navigationRef = useRef(navigationRefVal)

const {tracerProvider} = useEmbraceNativeTracerProvider();

return (
// `NavigationContainer` is waiting for what `useNavigationContainerRef` is returning (both exported from `@react-navigation/native`)
<NavigationContainer ref={navigationRefVal}>
<EmbraceNavigationTracker
ref={navigationRef}
tracerProvider={tracerProvider}
screenAttributes={{
"static.attribute": 123456,
"custom.key": "abcd...",
}}>
<Screens... />
</EmbraceNavigationTracker>
</NavigationContainer>
);
}