155 lines
4.3 KiB
Plaintext
155 lines
4.3 KiB
Plaintext
---
|
|
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';
|
|
|
|
<Callout>
|
|
Looking for a step-by-step tutorial? Check out the [React Native analytics guide](/guides/react-native-analytics).
|
|
</Callout>
|
|
|
|
## Installation
|
|
|
|
<Steps>
|
|
### 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
|
|
|
|
<CommonSdkConfig />
|
|
</Steps>
|
|
|
|
## Usage
|
|
|
|
### Track event
|
|
|
|
```typescript
|
|
op.track('my_event', { foo: 'bar' });
|
|
```
|
|
|
|
### Navigation / Screen views
|
|
|
|
<Tabs items={['expo-router', 'react-navigation (simple)']}>
|
|
<Tab value="expo-router">
|
|
```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])
|
|
// ...
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
<Tab value="react-navigation (simple)">
|
|
```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 (
|
|
<NavigationContainer
|
|
ref={navigationRef}
|
|
onReady={handleNavigationStateChange}
|
|
onStateChange={handleNavigationStateChange}
|
|
>
|
|
<Stack.Navigator />
|
|
</NavigationContainer>
|
|
)
|
|
}
|
|
```
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
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.
|