Skip to main content
The Formo React Native SDK is designed for mobile apps and implements the standard Events API with rich mobile context including device information, network status, and app metadata.

Installation

Install the SDK and its required peer dependency:
For automatic device info detection (version, build number, device model), install one of:
If neither is installed, provide app metadata via the app option instead. For Android install attribution (knowing which site or campaign a user came from before installing), also install:
This one requires a native rebuild of your Android app. Without it the SDK still works; install attribution is simply skipped, and a warning is logged on startup. See Web-to-mobile attribution.

iOS Setup (bare React Native only)

If you’re using bare React Native (not Expo), run pod install after adding native dependencies:
Expo projects handle native linking automatically, so no pod install is needed.

Quick Start

Wrap your app with the FormoAnalyticsProvider:
For apps using Wagmi, enable native integration for automatic wallet event tracking:

Code examples

React Native

examples/react-native

Track screen views

Use the screen() method to track screen views, the mobile equivalent of page views:
The screen() method signature is:
Include formo in the dependency array. The SDK initializes asynchronously, so including it ensures the screen event fires once initialization completes.
Screen views are sent as page events so they flow through the same analytics as web page views. The screen name is recorded in a page_url that mirrors a web URL:
Your bundle ID takes the place of the hostname and the screen name takes the place of the path — structurally the same as https://app.example.com/wallet. Formo therefore reads them with the same URL parsing it uses for web: the bundle ID becomes the origin and the screen becomes the page_path, so screens appear alongside web pages in reports like Top Pages.
Requires SDK 1.0.1 or later. Earlier versions sent app://Wallet, where the screen name occupies the hostname slot and there is no path at all — URL parsers return an empty path for that shape, so those screen views do not appear in Top Pages. Upgrading is the fix.
A few consequences worth knowing:
  • Screen names containing ? or # are percent-encoded, so a name like Checkout?coupon=X cannot truncate the path. / is left alone, since router-style names are meant to be path segments.
  • The bundle ID is the grouping key, not your app’s display name. Renaming your app therefore does not split its history.
  • Set app.bundleId explicitly (see App metadata) if you run in Expo Go or on React Native Web. In Expo Go the native modules report Expo Go’s own bundle ID, and on the web nothing resolves one at all.

React Navigation

Automatically track all screen transitions:

Mobile lifecycle events

The SDK automatically tracks application lifecycle events following the Segment/RudderStack specification: Lifecycle events are enabled by default and require asyncStorage to be provided for accurate install/update detection. To disable:

Opt-in lifecycle events

Two more are available but off by default, because enabling either changes how your app behaves: Application Foregrounded marks the same transition as Application Opened with from_background: true, so enabling it doubles your foreground event volume without adding information. It exists for consumers that key on the Segment spec name directly — for example dashboards being migrated from Segment or RudderStack. Application Crashed installs a global JavaScript error handler. Your previous handler always runs afterwards, so React Native’s redbox and any crash reporter you already use keep working. It reports message, name, stack and fatal.
autocapture: true does not enable these two — they must be named individually. Crash tracking is native only: on React Native Web an uncaught error goes to window.onerror and never reaches the handler the SDK installs.

Push notification events

Push delivery is invisible to JavaScript without a native module, so these are not autocaptured. Call them from your own push handler:
They emit Push Notification Received, Push Notification Tapped and Push Notification Bounced respectively. Any properties are accepted; the Segment spec suggests campaign_id, campaign_name, message_id, action, title and body.
The SDK detects app version and build from expo-application, react-native-device-info, or the app option (in that order). If none are available, version and build will be empty strings.

Identify users

Call identify() after a user connects their wallet:
When using Wagmi integration, wallet connections are automatically tracked. You only need to call identify() manually if you want to associate additional user data or use a custom user ID.

Track custom events

Track custom events with the track() method:
Parse UTM parameters and referral codes from deep links:
The SDK automatically extracts and stores:
  • UTM parameters (utm_source, utm_medium, utm_campaign, utm_term, utm_content)
  • Referral codes (ref, referral, refcode, referrer_code)
Example deep link: myapp://home?utm_source=twitter&utm_campaign=launch&ref=friend123

Web-to-mobile attribution

Deep link attribution tells you where a user came from once the app is already installed. Web-to-mobile attribution answers the earlier question: which site or campaign led someone to install the app in the first place.

Android

Google Play passes a referrer through the install, so this is captured reliably. Point your marketing links at your Play Store listing with a referrer parameter:
On first launch the SDK reads that value and attaches it to the Application Installed event, and to the traffic source used by subsequent events:
Requires react-native-play-install-referrer and a native rebuild; see Installation. The lookup runs once, on the first launch after install.

iOS

Not supported. Apple does not expose an install-referrer API, so an install cannot be attributed to a referring website from within the SDK. This requires a third-party attribution service such as Branch or AppsFlyer. On iOS this capture is a no-op; deep link attribution still works normally.

Configuration

Provider props

Example

App metadata

The SDK automatically detects app information from your app’s native configuration:
  • app_name - from your app’s display name
  • app_version - from your app’s version (e.g., 2.1.0)
  • app_build - from your app’s build number (e.g., 42)
  • app_bundle_id - from your bundle/package identifier
To override the auto-detected values, provide custom app information:

Tracking control

Control tracking behavior for different environments or chains:

Autocapture

Control which wallet events are automatically captured:
Two options are off unless named explicitly, because enabling either changes how the app behaves. autocapture: true does not turn them on:
autocapture.deepLinks controls only the event. Parsing a deep link’s UTM parameters into event context is separate, under attribution.deeplinks. Turning either off leaves the other working.

Attribution

Control deep link attribution and web-to-mobile attribution capture. Both sources are on by default and can be turned off individually:
Passing attribution: false disables both.

Logging

Enable debug logging during development:

Ready callback

Execute code when the SDK is fully initialized:
Comply with privacy regulations using built-in consent management:
When opting out, track the opt-out event before calling optOutTracking() so it gets recorded. When opting in, call optInTracking() first, then track the opt-in event.

Wagmi integration

When Wagmi integration is enabled, the SDK automatically tracks:
Use the same QueryClient instance for both Wagmi and Formo to avoid creating multiple cache instances.

Mobile context

The SDK automatically enriches every event with mobile-specific context:

Session management

The SDK assigns a session_id to every event. A session groups one user’s burst of activity into a single visit, and powers the Sessions, Session duration, and Bounce rate metrics on your dashboard. No configuration is required.
This differs from the web SDK, where session_id is derived server-side as a daily-changing value. That derivation relies on the request’s origin, IP and browser user agent (signals a native app does not provide meaningfully), so the mobile SDK supplies its own session instead.
Reset the current user session:

Manual event flushing

Force flush pending events (useful before app backgrounding):
The SDK automatically flushes events when the app goes to background.

Verification

To verify the SDK is working:
  1. Enable debug logging in development
  2. Trigger a screen view or custom event
  3. Check the console for event logs
  4. Verify events appear in the Activity page on your Formo dashboard

Peer dependencies