@nexly/react-native
v1.0.0
Published
React Native bindings for Nexly: fetch transport, AsyncStorage IDs, AppState engagement on top of @nexly/core
Maintainers
Readme
@nexly/react-native
React Native SDK for Nexly. Implements NexlyBase with:
fetch({ keepalive: true })transport,- visitor/session IDs persisted via
@react-native-async-storage/async-storage, - device metadata via
Platform,Dimensions,PixelRatio, - engagement tracking driven by
AppState(active seconds, heartbeat,session_ping).
Install
npm install @nexly/react-native @react-native-async-storage/async-storagereact and react-native must already be installed in your app.
Usage
import { NexlyProvider, useNexlyClient } from '@nexly/react-native'
export default function App() {
return (
<NexlyProvider appId="your-app-id" ingestKey="your-ingest-key" autoEngagement initialScreen="Home">
<Root />
</NexlyProvider>
)
}
function Root() {
const client = useNexlyClient()
return (
<Button
title="Upgrade"
onPress={() => client?.customEvent('upgrade_clicked', { plan: 'pro' })}
/>
)
}Screen views and paths
React Native has no URL, so Nexly uses a manual screen name as the path:
client.setScreen('Settings')— updates the screen used aspathon future events.client.screenview('Settings')— records that the user viewed a new screen.
On the ingest wire, a screen view is stored as a pageview event with
context.path set to the screen name. That keeps mobile screens in the same
Pages dashboard, filters, and session metrics as web routes, while the React
Native API still uses screenview() because that is the vocabulary app
developers expect.
Call screenview() only when the user actually views a different screen or
route. Do not use it for button taps, form input, tab content changes inside the
same screen, or other interactions. Send those with client.customEvent(...)
or client.event(...) instead; they still carry the current screen as path.
Hook it up to your router of choice. Example with @react-navigation/native:
<NavigationContainer
onStateChange={(state) => {
const route = state?.routes[state.index ?? 0]
if (route) client?.screenview(route.name)
}}
>
...
</NavigationContainer>If you pass initialScreen, you do not need to send an extra screenview() for
that same screen during the first render. Send the first manual screenview()
from your navigator when it reports a route change.
Engagement
autoEngagement attaches an AppState listener that:
- Increments
active_secondsonly while the app is foregrounded. - Sends a
heartbeatevery 60 s (lifecycle event for realtime dashboards). - Sends
session_pingwhen the app goes to background, andsession_endon provider unmount.
No scroll/click tracking (those are DOM-only); if you want tap analytics, send custom engagement events yourself.
startEngagement() is idempotent — calling it again stops the previous subscription first, so Fast Refresh or double-mounts cannot produce duplicate listeners.
Privacy mode (no device storage)
Pass privacyMode to the provider (or Nexly.init({ privacyMode: true })) and Nexly never reads or writes AsyncStorage for its visitor / session identifiers. Events go out without client-side IDs; the Nexly collector derives a daily-rotating visit fingerprint server-side instead. Cross-day returning-visitor metrics are not available in this mode.
Dashboard setup
Enable Mobile apps in your app's Ingest settings in the Nexly dashboard before sending native events. This allows React Native traffic from the package's synthetic origin and makes React Native sources visible in Technology analytics.
Native clients report as:
rn-iosfor iOS and other Apple native runtimes,rn-androidfor Android,rn-webwhen running through React Native Web.
In Technology analytics, native React Native traffic is labelled as React Native with the appropriate OS and mobile device type. React Native Web uses the browser's normal web metadata.
