Add Sumly to a React Native or Expo app
One TypeScript file, no native module and no new build step. It sends screens and events under the person RevenueCat knows, so each purchase shows the screens and the source that came before it.
Step by step
- 1
In Sumly, open Visitors and copy your project's public key (
sl_…). Save the SDK into your app withcurl -o sumly.ts https://sumly.dev/sdk/sumly.ts, and add AsyncStorage (npx expo install @react-native-async-storage/async-storage) so the queue survives a restart. - 2
At start, call
Sumly.init({ siteKey: 'sl_…', storage: AsyncStorage }). AfterPurchases.configure, and again after eachPurchases.logInorlogOut, callSumly.identify(await Purchases.getAppUserID()). - 3
Count screens: with Expo Router,
Sumly.screen(pathname)in the root layout; with React Navigation, on the container'sonReadyandonStateChange. They show on the project's Sources list within 15 seconds, as Mobile SDK.
Once, as the app starts.
// App.tsx
import AsyncStorage from '@react-native-async-storage/async-storage';
import Purchases from 'react-native-purchases';
import { Sumly } from './sumly'; // https://sumly.dev/sdk/sumly.ts
Sumly.init({ siteKey: 'sl_your_key', storage: AsyncStorage, appVersion: '1.4.0' });
await Purchases.configure({ apiKey: REVENUECAT_KEY });
Sumly.identify(await Purchases.getAppUserID());
// after signing in or out
await Purchases.logIn(String(user.id));
Sumly.identify(await Purchases.getAppUserID());
Or let your coding assistant do it
Paste this into Claude Code, Cursor or Codex in your project. It fits the code to how your project is built, asks you for the dashboard steps and leaves the keys to you.
See what it says
Set up React Native and Expo for Sumly in this project.
Sumly (https://sumly.dev) shows revenue next to the visits and app users it came from. The full guide is https://sumly.dev/install/react-native; read it if anything below is unclear.
Steps:
1. In Sumly, open Visitors and copy your project's public key (`sl_…`). Save the SDK into your app with `curl -o sumly.ts https://sumly.dev/sdk/sumly.ts`, and add AsyncStorage (`npx expo install @react-native-async-storage/async-storage`) so the queue survives a restart.
2. At start, call `Sumly.init({ siteKey: 'sl_…', storage: AsyncStorage })`. After `Purchases.configure`, and again after each `Purchases.logIn` or `logOut`, call `Sumly.identify(await Purchases.getAppUserID())`.
3. Count screens: with Expo Router, `Sumly.screen(pathname)` in the root layout; with React Navigation, on the container's `onReady` and `onStateChange`. They show on the project's Sources list within 15 seconds, as Mobile SDK.
Setup: Once, as the app starts.
```
// App.tsx
import AsyncStorage from '@react-native-async-storage/async-storage';
import Purchases from 'react-native-purchases';
import { Sumly } from './sumly'; // https://sumly.dev/sdk/sumly.ts
Sumly.init({ siteKey: 'sl_your_key', storage: AsyncStorage, appVersion: '1.4.0' });
await Purchases.configure({ apiKey: REVENUECAT_KEY });
Sumly.identify(await Purchases.getAppUserID());
// after signing in or out
await Purchases.logIn(String(user.id));
Sumly.identify(await Purchases.getAppUserID());
```
Expo Router: In the root layout, as Expo's own screen tracking guide does it.
```
// app/_layout.tsx
import { usePathname } from 'expo-router';
import { useEffect } from 'react';
const pathname = usePathname();
useEffect(() => { Sumly.screen(pathname); }, [pathname]);
```
React Navigation: onStateChange does not run for the first screen, so onReady counts that one.
```
const navigationRef = useNavigationContainerRef();
<NavigationContainer
ref={navigationRef}
onReady={() => Sumly.screen(navigationRef.getCurrentRoute()?.name ?? 'App')}
onStateChange={() => Sumly.screen(navigationRef.getCurrentRoute()?.name ?? 'App')}
>
```
Consent: Where your app asks first.
```
Sumly.init({ siteKey: 'sl_your_key', storage: AsyncStorage, waitForConsent: true });
Sumly.consent(true); // when the person agrees
Sumly.consent(false); // when they refuse, or take it back
```
Own domain: Optional: your own address takes app events too.
```
Sumly.init({ siteKey: 'sl_your_key', storage: AsyncStorage, endpoint: 'https://signal.example.com' });
```
Keep in mind: Offline, screens and events wait in the queue (kept across restarts with AsyncStorage) and go once the network is back, dated when they happened. On the web (Expo web, React Native Web), use the website script instead.
How to work:
- Look at how this project is built first, and fit the code to its framework and its way of doing things; the examples above are a starting point, not something to paste as is.
- Steps that happen in a dashboard (Sumly, or React Native and Expo's own) are mine: tell me exactly what to click, then wait for me.
- Keys the code needs belong in environment variables, never in the code or the repository. Never ask me to paste a secret key into this chat; tell me which variable to set.
- Change only what this needs, show me the changes before you commit, and tell me how to check that it works.
- sl_your_key stands for the project's public key; it is on the Visitors page in Sumly. Ask me for it.
Consent
Where your app asks first, start with waitForConsent: nothing is kept or sent until consent(true), and consent(false) stops sending and empties the queue. The answer is remembered.
Purchases
Purchases do not come through the app: Sumly reads them from RevenueCat, Adapty or Superwall. Give identify the same person they know: RevenueCat's app user id (the anonymous one too), or the user id you pass to Adapty.identify or Superwall.identify. Each purchase then shows the screens and the source that came before it.
Your own domain
Optional. The own address of your site's script (one DNS record on Visitors, on Starter and Growth) takes app events too: give it as the endpoint and the app sends to /api/v1/events there.
Good to know
- Offline, screens and events wait in the queue (kept across restarts with AsyncStorage) and go once the network is back, dated when they happened.
- On the web (Expo web, React Native Web), use the website script instead.
From React Native and Expo's own documentation, checked 4 November 2026: docs.expo.dev/router/reference/screen-tracking, reactnavigation.org/docs/screen-tracking, revenuecat.com/docs/customers/identifying-customers .
Other apps
Try it with your own projects
Sign in with Google or a code by e-mail and connect your first project. Free for one project, and 14 days of a paid plan with no card.
Start freeOr look around first: open the live demo.