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:
- Which step loses the most users (by volume, not just percentage)
- Whether mobile and desktop users abandon at different points
- Whether a recent release introduced a new drop-off spike
Install the SDK
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:
// 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.
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
| Step | Event name |
|---|---|
| App opened first time | app_opened |
| Started signup | signup_started |
| Created account | account_created |
| Verified email | email_verified |
| Completed profile | profile_completed |
| Connected first integration | integration_connected |
| Took first meaningful action | first_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.
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
Open Funnel → New funnel
Name it something descriptive like "Core onboarding" or "Trial activation."
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.
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
- Time on step - if average time is unusually high, users are confused, not skipping
- OS split - if Android drops off 2× more than iOS at the same step, it's likely a layout or permission issue
- Device - older phones failing an API call looks like drop-off in the funnel
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 →
