·7 min read

React Native Onboarding Analytics: Track Where Users Drop Off

Most React Native apps track installs and signups. Very few track what happens between them. This guide covers how to instrument your onboarding flow and see per-step drop-off in a live funnel.

Why per-step analytics matter

A total completion rate tells you the outcome. It doesn't tell you which step is the problem. If 60% of your users never finish onboarding and you only have a start-and-end event, you'll spend weeks A/B testing the wrong thing.

Step-level analytics gives you:

Install the SDK

bash
npm install @onramp-sdk/react-native
# or
yarn add @onramp-sdk/react-native

The SDK works with both bare React Native and Expo. It uses AsyncStorage for anonymous user identity - no cookies, no tracking pixels.

Initialise once at app startup

Call OnRamp.init() in your root component before any screens render:

tsx
// App.tsx
import { useEffect } from 'react'
import { OnRamp } from '@onramp-sdk/react-native'

export default function App() {
  useEffect(() => {
    OnRamp.init({
      apiKey: 'onr_your_key_here',
    })
  }, [])

  return <NavigationContainer>...</NavigationContainer>
}

Tip

Create a separate app in the OnRamp dashboard for development - your dev environment API key keeps test events out of production data.

Track each onboarding step

Call OnRamp.step() immediately after the user completes an action - not when a screen loads. Tracking on load inflates your completion numbers because users who bounce immediately still count as having "completed" the step.

tsx
import { OnRamp } from '@onramp-sdk/react-native'

// Good: fire after the action completes
async function handleSignup(email: string, password: string) {
  await createAccount(email, password)
  OnRamp.step('account_created')
}

// Wrong: fire on screen mount
useEffect(() => {
  OnRamp.step('account_created') // fires even for users who immediately leave
}, [])

Recommended step names for a typical onboarding flow

StepEvent name
App opened first timeapp_opened
Started signupsignup_started
Created accountaccount_created
Verified emailemail_verified
Completed profileprofile_completed
Connected first integrationintegration_connected
Took first meaningful actionfirst_action

Use underscores, not spaces. Capitalisation matters - account_created and Account Created are separate events in the funnel.

Add properties to diagnose segments

Properties let you split funnel data by plan type, signup source, or device - so you can tell whether a drop-off is universal or only affects one segment.

tsx
OnRamp.step('account_created', {
  properties: {
    plan: 'trial',
    signup_method: 'google_oauth',
    device_os_version: Platform.OS,
  },
})

Insight

Split your funnel by signup_method to see whether account-creation paths behave differently in your product. Do not assume a signup method is causal without comparing equivalent cohorts.

Build the funnel in the dashboard

1

Open Funnel → New funnel

Name it something descriptive like "Core onboarding" or "Trial activation."

2

Add your steps in order

Type each step name exactly as you pass it to OnRamp.step(). Add them in the order a user should complete them.

3

Set a conversion window

Choose a conversion window that matches your product's natural return cycle, then keep it consistent when comparing cohorts.

Once saved, the funnel retroactively populates with any matching events that have already arrived.

What to look for

Per-step drop-off

Drop-off = 1 − (users who completed step N ÷ users who entered step N)

Example: 1 − (210 ÷ 400) = 47.5% drop-off at step 3

The step with the highest volume of drops is your priority - not the step with the highest drop-off percentage. A 15% rate at step 2 with 800 users is more important than a 40% rate at step 6 with 50 users.

Signals to check for each high-drop step

Common React Native–specific gotchas

Permission prompts cause phantom drop-off. If your onboarding asks for push notifications or camera access early, users who tap "Don't allow" often quit the whole flow. Consider deferring the ask until after the aha moment.

Deep link handling. If your email verification redirects back to the app via a deep link, confirm that the redirect actually fires OnRamp.step('email_verified') - some universal link setups silently drop the user into the wrong screen.

Background/foreground re-init. Don't call OnRamp.init() on every app foreground. The SDK handles session continuity; re-initialising resets the in-flight batch.


See your React Native onboarding funnel

Three lines of code to your first funnel

Install the SDK, call OnRamp.step() at each milestone, and see per-step drop-off live - no data team, no dashboards to configure.

Start free trial →