Installation
In your React Native or Expo project add the posthog-react-native
package to your project as well as the required peer dependencies.
Expo apps
expo install posthog-react-native expo-file-system expo-application expo-device expo-localization
React Native apps
yarn add posthog-react-native @react-native-async-storage/async-storage react-native-device-info# ornpm i -s posthog-react-native @react-native-async-storage/async-storage react-native-device-info
Configuration
With the PosthogProvider
The recommended way to set up PostHog for React Native is to use the PostHogProvider
which utilizes the Context API to pass the PostHog client around, enable autocapture, and ensure that the queue is flushed at the right time:
// App.(js|ts)import { usePostHog, PostHogProvider } from 'posthog-react-native'...export function MyApp() {return (<PostHogProvider apiKey="<ph_project_api_key>" options={{host: '<ph_instance_address>',}}><MyComponent /></PostHogProvider>)}// Now you can simply access PostHog elsewhere in the app like so:const MyComponent = () => {const posthog = usePostHog()useEffect(() => {posthog.capture("MyComponent loaded", { foo: "bar" })}, [])}
Configuration
Without the PosthogProvider
Due to the async nature of React Native, PostHog needs to be initialized asynchronously for the persisted state to load properly. The PosthogProvider
takes care of this under-the-hood but you can alternatively create the instance yourself like so:
// posthog.tsimport PostHog from 'posthog-react-native'export let posthog: PostHog | undefined = undefinedexport const posthogAsync: Promise<PostHog> = PostHog.initAsync('<ph_project_api_key>', {host: '<ph_instance_address>'})posthogAsync.then(client => {posthog = client})// app.tsimport { posthog, posthogAsync} from './posthog'export function MyApp1() {useEffect(async () => {// Use posthog optionally with the possibility that it may still be loadingposthog?.capture('MyApp1 loaded')// OR use posthog via the promise(await posthogAsync).capture('MyApp1 loaded')}, [])return <View>Your app code</View>}// You can even use this instance with the PostHogProviderexport function MyApp2() {return <PostHogProvider client={posthogAsync}>{/* Your app code */}</PostHogProvider>}
Configuration options
You can further customize how PostHog works through its configuration on initialization.
export const posthog = await PostHog.initAsync("<ph_project_api_key>", {// PostHog API hosthost?: string = "https://app.posthog.com",// The number of events to queue before sending to PostHog (flushing)flushAt?: number = 20,// The interval in milliseconds between periodic flushesflushInterval?: number = 10000// If set to false, tracking will be disabled until `optIn` is calledenable?: boolean = true,// Whether to track that `getFeatureFlag` was called (used by Expriements)sendFeatureFlagEvent?: boolean = true,// Whether to load feature flags when initialised or notpreloadFeatureFlags?: boolean = true,// How many times we will retry HTTP requestsfetchRetryCount?: number = 3,// The delay between HTTP request retriesfetchRetryDelay?: number = 3000,// For Session Analysis how long before we expire a sessionsessionExpirationTimeSeconds?: number = 1800 // 30 mins// Whether to post events to PostHog in JSON or compressed formatcaptureMode?: 'json' | 'form'})
Capturing events
Currently, the only functionality this library supports is sending events, which can be done using the capture
and capture_batch
methods. User properties and groups can both be set as props on events.
let mut event = Event::new("<event_name>", "<distinct_id>");event.insert_prop("key1", "value1").unwrap();event.insert_prop("key2", vec!["a", "b"]).unwrap();client.capture(event).unwrap();
let event1 = posthog_rs::Event::new("event 1", "1234");let event2 = posthog_rs::Event::new("event 2", "1234");client.capture_batch(vec![event1, event2]).unwrap();