React Navigation Integration
Integrate the Tappd Mobile SDK with React Navigation for automatic screen tracking.
Overview
React Navigation is the most popular navigation library for React Native. This guide shows how to integrate the Tappd SDK for automatic screen tracking.
Installation
If you haven't already, install React Navigation:
bash
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-contextBasic Setup
Using useFocusEffect Hook
The simplest way is to use the useFocusEffect hook in each screen:
javascript
import React from 'react';
import { View, Text } from 'react-native';
import { useFocusEffect } from '@react-navigation/native';
import { useTappd } from '../contexts/TappdContext';
function HomeScreen() {
const tappd = useTappd();
useFocusEffect(
React.useCallback(() => {
// Screen comes into focus
tappd.trackScreen('HomeScreen', {
category: 'main',
section: 'dashboard'
});
return () => {
// Screen goes out of focus (optional cleanup)
};
}, [])
);
return (
<View>
<Text>Home Screen</Text>
</View>
);
}Navigation Container Setup
Create Navigation Helper
Create a helper to track all screen changes:
javascript
// utils/navigationTracker.js
import { useEffect, useRef } from 'react';
import { useNavigationContainerRef } from '@react-navigation/native';
export function useNavigationTracking(tappd) {
const navigationRef = useNavigationContainerRef();
const routeNameRef = useRef();
useEffect(() => {
if (!navigationRef || !tappd) return;
const onStateChange = async () => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.getCurrentRoute()?.name;
if (previousRouteName !== currentRouteName) {
// Track screen view
await tappd.trackScreen(currentRouteName, {
previousScreen: previousRouteName
});
}
routeNameRef.current = currentRouteName;
};
navigationRef.addListener('state', onStateChange);
return () => {
navigationRef.removeListener('state', onStateChange);
};
}, [navigationRef, tappd]);
}Use in App
javascript
// App.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { useTappd } from './contexts/TappdContext';
import { useNavigationTracking } from './utils/navigationTracker';
const Stack = createNativeStackNavigator();
function App() {
const tappd = useTappd();
const navigationRef = React.useRef();
useNavigationTracking(tappd);
return (
<NavigationContainer ref={navigationRef}>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}Advanced: Custom Navigator
Create a wrapper that automatically tracks screens:
javascript
// components/TrackedStackNavigator.js
import React from 'react';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { useNavigationContainerRef } from '@react-navigation/native';
import { useTappd } from '../contexts/TappdContext';
const Stack = createNativeStackNavigator();
export function TrackedStackNavigator({ screens }) {
const tappd = useTappd();
const navigationRef = useNavigationContainerRef();
const routeNameRef = React.useRef();
React.useEffect(() => {
if (!navigationRef || !tappd) return;
const unsubscribe = navigationRef.addListener('state', async (e) => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.getCurrentRoute()?.name;
if (previousRouteName !== currentRouteName) {
await tappd.trackScreen(currentRouteName, {
previousScreen: previousRouteName,
timestamp: new Date().toISOString()
});
}
routeNameRef.current = currentRouteName;
});
return unsubscribe;
}, [navigationRef, tappd]);
return (
<Stack.Navigator>
{screens.map((screen) => (
<Stack.Screen
key={screen.name}
name={screen.name}
component={screen.component}
options={screen.options}
/>
))}
</Stack.Navigator>
);
}
// Usage
<TrackedStackNavigator
screens={[
{ name: 'Home', component: HomeScreen },
{ name: 'Profile', component: ProfileScreen }
]}
/>Tab Navigation
For Tab Navigators, track when tabs are focused:
javascript
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { useFocusEffect } from '@react-navigation/native';
const Tab = createBottomTabNavigator();
function HomeTab() {
const tappd = useTappd();
useFocusEffect(
React.useCallback(() => {
tappd.trackScreen('HomeTab');
}, [])
);
return <HomeScreen />;
}
function ProfileTab() {
const tappd = useTappd();
useFocusEffect(
React.useCallback(() => {
tappd.trackScreen('ProfileTab');
}, [])
);
return <ProfileScreen />;
}
function TabNavigator() {
return (
<Tab.Navigator>
<Tab.Screen name="HomeTab" component={HomeTab} />
<Tab.Screen name="ProfileTab" component={ProfileTab} />
</Tab.Navigator>
);
}Tracking Navigation Events
Track navigation actions:
javascript
import { useNavigation } from '@react-navigation/native';
function MyScreen() {
const navigation = useNavigation();
const tappd = useTappd();
const handleNavigate = async (screenName, params) => {
// Track navigation event
await tappd.track('navigation.navigated', {
from: 'CurrentScreen',
to: screenName,
params: params
});
// Navigate
navigation.navigate(screenName, params);
};
return (
<Button
title="Go to Profile"
onPress={() => handleNavigate('Profile')}
/>
);
}Deep Linking
The SDK automatically tracks deep links. For manual tracking:
javascript
import { Linking } from 'react-native';
import { useTappd } from '../contexts/TappdContext';
function App() {
const tappd = useTappd();
useEffect(() => {
// Get initial URL
Linking.getInitialURL().then((url) => {
if (url) {
// SDK automatically tracks deep_link.opened
// But you can track additional info:
tappd.track('deep_link.handled', {
url: url,
source: 'cold_start'
});
}
});
// Listen for deep links
const subscription = Linking.addEventListener('url', (event) => {
tappd.track('deep_link.handled', {
url: event.url,
source: 'warm_start'
});
});
return () => {
subscription.remove();
};
}, []);
return (
// Your app
);
}Screen Tracking with Params
Track screen with navigation parameters:
javascript
function ProductScreen({ route }) {
const tappd = useTappd();
const { productId } = route.params;
useFocusEffect(
React.useCallback(() => {
tappd.trackScreen('ProductScreen', {
productId: productId,
category: 'ecommerce'
});
}, [productId])
);
return (
// Screen content
);
}Best Practices
- Use useFocusEffect - Tracks screen when it comes into focus
- Track with context - Include navigation params in screen tracking
- Track navigation actions - Track user navigation behavior
- Handle deep links - SDK handles automatically, but track additional info if needed
- Consistent naming - Use consistent screen names across your app
Example: Complete Setup
javascript
// App.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import TappdSDK from '@tappd/mobile-sdk';
import { TappdProvider } from './contexts/TappdContext';
import HomeScreen from './screens/HomeScreen';
import ProfileScreen from './screens/ProfileScreen';
const Stack = createNativeStackNavigator();
const tappd = new TappdSDK({
appId: 'YOUR_APP_ID',
enableAutoScreenTracking: true
});
function App() {
return (
<TappdProvider value={tappd}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
</NavigationContainer>
</TappdProvider>
);
}
export default App;javascript
// screens/HomeScreen.js
import React from 'react';
import { View, Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { useFocusEffect } from '@react-navigation/native';
import { useTappd } from '../contexts/TappdContext';
function HomeScreen() {
const navigation = useNavigation();
const tappd = useTappd();
useFocusEffect(
React.useCallback(() => {
tappd.trackScreen('HomeScreen');
}, [])
);
const handleNavigate = async () => {
await tappd.track('navigation.button_pressed', {
buttonId: 'go_to_profile',
from: 'HomeScreen'
});
navigation.navigate('Profile');
};
return (
<View>
<Button title="Go to Profile" onPress={handleNavigate} />
</View>
);
}
export default HomeScreen;Next Steps
- API Reference - Complete method documentation
- Examples - More React Navigation examples
- Configuration - Configure screen tracking behavior
