--- title: React Native --- import Link from 'next/link'; import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; import { Step, Steps } from 'fumadocs-ui/components/steps'; import { DeviceIdWarning } from '@/components/device-id-warning'; import { PersonalDataWarning } from '@/components/personal-data-warning'; import { Callout } from 'fumadocs-ui/components/callout'; import CommonSdkConfig from '@/components/common-sdk-config.mdx'; Looking for a step-by-step tutorial? Check out the [React Native analytics guide](/guides/react-native-analytics). ## Installation ### Install dependencies We're dependent on `expo-application` for `buildNumber`, `versionNumber` (and `referrer` on android) and `expo-constants` to get the `user-agent`. ```npm npm install @openpanel/react-native npx expo install expo-application expo-constants ``` ### Initialize On native we use a clientSecret to authenticate the app. ```typescript import { OpenPanel } from '@openpanel/react-native'; const op = new OpenPanel({ clientId: '{YOUR_CLIENT_ID}', clientSecret: '{YOUR_CLIENT_SECRET}', }); ``` #### Options ## Usage ### Track event ```typescript op.track('my_event', { foo: 'bar' }); ``` ### Navigation / Screen views ```typescript import { usePathname, useSegments } from 'expo-router'; const op = new Openpanel({ /* ... */ }) function RootLayout() { // ... const pathname = usePathname() // Segments is optional but can be nice to have if you // want to group routes together // pathname = /posts/123 // segements = ['posts', '[id]'] const segments = useSegments() useEffect(() => { // Simple op.screenView(pathname) // With extra data op.screenView(pathname, { // segments is optional but nice to have segments: segments.join('/'), // other optional data you want to send with the screen view }) }, [pathname,segments]) // ... } ``` ```tsx import { createNavigationContainerRef } from '@react-navigation/native' import { Openpanel } from '@openpanel/react-native' const op = new Openpanel({ /* ... */ }) const navigationRef = createNavigationContainerRef() export function NavigationRoot() { const handleNavigationStateChange = () => { const current = navigationRef.getCurrentRoute() if (current) { op.screenView(current.name, { params: current.params, }) } } return ( ) } ``` For more information on how to use the SDK, check out the [Javascript SDK](/docs/sdks/javascript#usage). ## Offline support The SDK can buffer events when the device is offline and flush them once connectivity is restored. Events are stamped with a `__timestamp` at the time they are fired so they are recorded with the correct time even if they are delivered later. Two optional peer dependencies enable this feature: ```npm npm install @react-native-async-storage/async-storage @react-native-community/netinfo ``` Pass them to the constructor: ```typescript import { OpenPanel } from '@openpanel/react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import NetInfo from '@react-native-community/netinfo'; const op = new OpenPanel({ clientId: '{YOUR_CLIENT_ID}', clientSecret: '{YOUR_CLIENT_SECRET}', // Persist the event queue across app restarts storage: AsyncStorage, // Automatically flush the queue when the device comes back online networkInfo: NetInfo, }); ``` Both options are independent — you can use either one or both: - **`storage`** — persists the queue to disk so events survive app restarts while offline. - **`networkInfo`** — flushes the queue automatically when connectivity is restored. Without this, the queue is flushed the next time the app becomes active.