React Native SDK
Track events on iOS and Android with the FlashAnalytics React Native SDK.
The React Native SDK adds lifecycle capture, deep links, navigation tracking, JavaScript error capture, native crash reporting, experiment assignment, and push lifecycle helpers to iOS and Android apps.
Install
npm install @flash-analytics/react-native react-native-device-infocd ios && pod installreact-native-device-info is a peer dependency.
Initialize
import { FlashAnalytics } from '@flash-analytics/react-native';
const analytics = new FlashAnalytics({
appId: 'YOUR_APP_ID',
endpoint: 'https://api.flashanalytics.app',
captureAppLifecycle: true,
captureScreenViews: true,
captureDeepLinks: true,
captureErrors: true,
captureNativeCrashes: true,
captureVariants: true,
capturePushLifecycle: true,
pushTracking: {
android: {
defaultChannelId: 'flash-default',
defaultNotificationTtlMs: 5 * 60 * 1000,
},
},
});When captureAppLifecycle is enabled, app_openedis emitted only after the app actually reaches the foreground.
Auto capture
- App lifecycle via
captureAppLifecycle - Deep links via
captureDeepLinks - JavaScript errors via
captureErrors - Native crashes via
captureNativeCrashes - Experiment auto-assignment via
captureVariants - Push lifecycle helpers via
capturePushLifecycle
Navigation tracking
analytics.setNavigationRef(navigationRef, (routeName, params) => {
switch (routeName) {
case 'Home':
return '/home';
case 'BlogPost':
return `/blog/${(params as { post?: { id?: string } })?.post?.id ?? ''}`;
default:
return `/${routeName.toLowerCase()}`;
}
});
analytics.trackScreenChange('Checkout');Error tracking
try {
await riskyOperation();
} catch (error) {
analytics.trackError(error, 'network_failure');
}enableErrorTracking still exists for older setups, but new apps should use captureErrors.
Experiments
Enable captureVariants to keep a local cache of assignments in sync automatically. On each new session all experiments are fetched; after identify() only profile-mode assignments are refreshed; on session expiry only session-mode entries are removed.
// All cached assignments — no API call
const all = analytics.getAllExperiments();
// Single experiment — checks cache first, falls back to API if not found
const assignment = await analytics.getExperimentById('checkout-cta');
console.log(assignment?.variantName);
// Manual assignment (always calls the API)
const assignments = await analytics.autoAssignExperiments();
const variant = await analytics.assignExperiment('checkout-cta');Push lifecycle
notification_deliverednotification_openednotification_dismissednotification_action_clickednotification_expired
React Native JavaScript alone cannot observe every OS callback. iOS delivery and expiry require a UNNotificationServiceExtension. iOS open, dismiss, and action events require UNUserNotificationCenterDelegate. Android dismiss and action events require native BroadcastReceiver, PendingIntent, and sometimes WorkManagerwiring.
import { enableFlashPushTracking } from '@flash-analytics/react-native';
const detachNativeTracking = analytics.attachNativeNotificationTracking();
enableFlashPushTracking({
appId: 'YOUR_APP_ID',
endpoint: 'https://api.flashanalytics.app',
android: {
defaultChannelId: 'flash-default',
defaultNotificationTtlMs: 5 * 60 * 1000,
},
});Session access
const session = analytics.getSession();
console.log(session?.id);
console.log(session?.estimatedExpiresAt);
console.log(session?.estimatedTtlMs);