Browse docs

Explore by section, then jump directly into a page.

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-info
cd ios && pod install

react-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_delivered
  • notification_opened
  • notification_dismissed
  • notification_action_clicked
  • notification_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);