TapCub is live — analytics, insights and live chat, free on one platform
Help center

How do I add TapCub to a React Native app?

Install @tapcub/react-native, register your Android and iOS identifiers, initialize with AsyncStorage and AppState, send screens from React Navigation, and optionally forward native crashes.

App analytics3 min readLast updated Nov 6, 2026TapCub team

Short answer

Register your Android applicationId and iOS bundle ID under App analytics › Configuration › SDK code, install @tapcub/react-native with @react-native-async-storage/async-storage, call TapCub.preInit(config, host) and await TapCub.init() at startup, and pass TapCub.navigationHook to NavigationContainer so screen changes are sent. The SDK runs in JavaScript (React Native 0.72 or newer); on iOS one Podfile line is still required.

1. Register both app identifiers

Open App analytics › Configuration › SDK code and click Add app identifier for the Android applicationId and for the iOS bundle ID. Data from an identifier that is not registered is dropped silently.

2. Install

npm install @tapcub/react-native @react-native-async-storage/async-storage

On iOS, autolinking adds this package's pod, which depends on the TapCub pod. That pod is not on the CocoaPods trunk, so add it to ios/Podfile inside your app target and run pod install:

pod 'TapCub', :git => 'https://github.com/tapcub/tapcub-ios.git', :tag => '0.1.0'

3. Initialize

import AsyncStorage from '@react-native-async-storage/async-storage';
import { AppState, Dimensions, Platform } from 'react-native';
import { TapCub } from '@tapcub/react-native';

TapCub.preInit(
  { siteKey: 'YOUR_SITE_KEY', appId: 'com.example.app' },
  { asyncStorage: AsyncStorage, appState: AppState, platform: Platform, dimensions: Dimensions },
);
// after the user accepts the privacy policy:
await TapCub.init();

The second argument is the host object; the SDK does not import react-native itself, so pass what it should use:

  • asyncStorage keeps the event queue across restarts. Without it the queue lives in memory only.
  • appState records foreground and background. Without it they are not recorded.
  • platform reports iOS or Android correctly. Without it events are reported as Android.

appId must match the registered identifier. For China mode, pass region: 'cn', call init after consent and then TapCub.grantConsent(['analytics']). Calling track before preInit throws TapCub.preInit() first.

4. Track screens

<NavigationContainer onStateChange={TapCub.navigationHook}>
  {/* navigators */}
</NavigationContainer>

A change of the innermost route name sends one $screen_view; the same name twice in a row is not sent again. Without React Navigation, call TapCub.trackScreen('Home') yourself.

5. Events and identity

TapCub.track('purchase', { revenue: 19.9, currency: 'USD' });

TapCub.login(userId, { plan: 'pro' }, { type: 'login' });
TapCub.logout();

type may be login, email, mobile, openid, unionid or custom; email and mobile are hashed before sending. See Identify users.

6. Optional: native crashes

The JavaScript SDK sees JavaScript exceptions only. To also get native crashes, ANRs (Android 11+) and freezes (iOS), install the native SDKs and the package's TapCubCrash module:

  1. Android: add the com.tapcub:android dependency to android/app/build.gradle and call TapCubCrash.install(this) in Application.onCreate.
  2. iOS: with the Podfile line above in place, call [TapCubCrash install] in didFinishLaunchingWithOptions:.
  3. JavaScript: add nativeCrash: NativeModules.TapCubCrash to the host object.

Crashes recorded natively are handed to the JavaScript SDK on the next launch with the original crash time. Do not call preInit on the native side as well: that starts a second native SDK and every event is sent twice.

7. Verify

Run the app and open App analytics › Overview › Realtime. A start event and your first screen should arrive within seconds.

Troubleshooting

  • No data: identifier not registered, or init was never called.
  • No screens: navigationHook is not on NavigationContainer, or the state has no route name.
  • Events lost after restart: asyncStorage was not passed.
  • All events show as Android: platform was not passed.
  • pod install fails to find TapCub: the Podfile line is missing.

Related

Did this answer your question?

We use your answers to fix and expand this page.

See your data clearly. Find your growth.

Every click, backed by data. Install one line of code and see your first numbers in a minute.

No credit card · Free plans for analytics and chat · Cookieless analytics