Integration React Native
PostHogOfficialCreated by PostHog
- Skill
- Tool integration
- Data and AI
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a systematic workflow for adding PostHog analytics to React Native projects. It covers the installation of required dependencies, environment variable configuration, and implementation patterns for event tracking, user identification, and error monitoring. The guide emphasizes maintaining clean code by using environment variables for sensitive keys and following established patterns for React Navigation compatibility.
What it does
- Guides the installation of posthog-react-native and required peer dependencies.
- Provides a step-by-step workflow for setting up event tracking.
- Details the configuration of environment variables for project tokens and hosts.
- Defines patterns for identifying users during authentication flows.
- Outlines best practices for integrating error tracking in critical app paths.
- Ensures compatibility with React Navigation v7.
When to use it
- When you need to add product analytics to a new or existing React Native application.
- When you want to implement user identification for tracking authenticated sessions.
- When you need to capture errors and monitor critical user flows in your mobile app.
- When you require a standardized approach to managing PostHog configuration across development environments.
Advantages
- Promotes secure practices by mandating the use of environment variables.
- Ensures consistent implementation through a structured, multi-step workflow.
- Provides clear guidance on peer dependency requirements like react-native-svg.
- Supports robust analytics by including both client-side and server-side event tracking strategies.
Usage examples
- “How do I start integrating PostHog into my React Native app?”
- The agent will initiate the four-step workflow, starting with the setup phase to analyze your project and create an event tracking plan.
- “Where should I place the PostHogProvider in my React Native navigation structure?”
- The agent will advise placing the provider inside the NavigationContainer to ensure compatibility with React Navigation v7.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/posthog/integration-react-native/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip integration-react-native.zip -d .agents/skills
Documentation by PostHog
PostHog integration for React Native
This skill helps you add PostHog analytics to React Native applications.
Workflow
Follow these steps in order to complete the integration:
basic-integration-1.0-begin.md- PostHog Setup - Begin ← Start herebasic-integration-1.1-edit.md- PostHog Setup - Editbasic-integration-1.2-revise.md- PostHog Setup - Revisebasic-integration-1.3-conclude.md- PostHog Setup - Conclusion
Reference files
references/EXAMPLE.md- React Native example project codereferences/react-native.md- React native - docsreferences/identify-users.md- Identify users - docsreferences/basic-integration-1.0-begin.md- PostHog setup - beginreferences/basic-integration-1.1-edit.md- PostHog setup - editreferences/basic-integration-1.2-revise.md- PostHog setup - revisereferences/basic-integration-1.3-conclude.md- PostHog setup - conclusion
The example project shows the target implementation pattern. Consult the documentation for API details.
Key principles
Environment variables: Always use environment variables for PostHog keys. Never hardcode them.
Minimal changes: Add PostHog code alongside existing integrations. Don't replace or restructure existing code.
Match the example: Your implementation should follow the example project's patterns as closely as possible.
Framework guidelines
posthog-react-native is the React Native SDK package name
Use react-native-config to load POSTHOG_PROJECT_TOKEN and POSTHOG_HOST from .env (variables are embedded at build time, not runtime)
react-native-svg is a required peer dependency of posthog-react-native (used by the surveys feature) and must be installed alongside it
Place PostHogProvider INSIDE NavigationContainer for React Navigation v7 compatibility
Identifying users
Identify users during login and signup events. Refer to the example code and documentation for the correct identify pattern for this framework. If both frontend and backend code exist, pass the client-side session and distinct ID using X-POSTHOG-DISTINCT-ID and X-POSTHOG-SESSION-ID headers to maintain correlation.
Error tracking
Add PostHog error tracking to relevant files, particularly around critical user flows and API boundaries.
Files
- ATTRIBUTION.mdAdded by AutoGineer972 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md2.4 KiB
- references/EXAMPLE.md71.3 KiB
- references/basic-integration-1.0-begin.md2.1 KiB
- references/basic-integration-1.1-edit.md2.5 KiB
- references/basic-integration-1.2-revise.md937 B
- references/basic-integration-1.3-conclude.md1.6 KiB
- references/identify-users.md8.1 KiB
- references/react-native.md43.8 KiB
references/EXAMPLE.md
PostHog React Native Example Project
Repository: https://github.com/PostHog/context-mill Path: basics/react-native
README.md
PostHog React Native example
This is a bare React Native example (no Expo) demonstrating PostHog integration with product analytics, user identification, autocapture, and error tracking.
Features
Product analytics: Track user events and behaviors
Autocapture: Automatic touch event and screen view tracking
Error tracking: Capture and track errors manually
User authentication: Demo login system with PostHog user identification
Session persistence: AsyncStorage for maintaining user sessions across app restarts
Native navigation: React Navigation v7 with native stack navigator
Prerequisites
For iOS Development
You need a Mac with the following installed:
Xcode (from the Mac App Store)
Open App Store and search for "Xcode"
Install it (~12GB download)
After installing, open Xcode once to accept the license agreement
Xcode Command Line Tools
xcode-select --installCocoaPods (iOS dependency manager)
brew install cocoapodsOr without Homebrew:
sudo gem install cocoapods
For Android Development
Android Studio (the Android IDE)
brew install --cask android-studioOr download from: https://developer.android.com/studio
First-time Android Studio Setup
Open Android Studio
Complete the setup wizard (downloads Android SDK automatically)
Go to Settings → Languages & Frameworks → Android SDK
Ensure "Android SDK Platform 34" (or latest) is installed
Create an Android Emulator
In Android Studio: Tools → Device Manager
Click Create Device
Select a phone (e.g., "Pixel 7")
Download a system image (e.g., API 34)
Finish and click the Play button to launch
Environment Variables (add to
~/.zshrcor~/.bashrc)# Android SDK export ANDROID_HOME=$HOME/Library/Android/sdk export PATH=$PATH:$ANDROID_HOME/emulator export PATH=$PATH:$ANDROID_HOME/platform-tools # Java from Android Studio (required for Gradle) export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" export PATH=$JAVA_HOME/bin:$PATHThen run
source ~/.zshrcto apply.Create local.properties file (if SDK location is not detected) Create
android/local.propertieswith:sdk.dir=$HOME/Library/Android/sdkClear Gradle cache (required when jumping between different versions of Gradle)
rm -rf ~/.gradle/caches/modules-2/files-2.1/org.gradle.toolchains/foojay-resolver
Getting started
1. Install dependencies
npm install2. Configure environment variables
Create a .env file:
cp .env.example .envEdit .env and add your PostHog project token:
POSTHOG_PROJECT_TOKEN=phc_your_project_token_here
POSTHOG_HOST=https://us.i.posthog.comGet your PostHog project token from your PostHog project settings.
Note: The app will still run without a PostHog project token - analytics will simply be disabled.
3. Run on iOS
Install iOS dependencies (first time only):
cd ios && pod install && cd ..Run the app:
npm run iosNote: First build takes 5-10 minutes. Subsequent builds are much faster.
4. Run on Android
Make sure an Android emulator is running (from Android Studio Device Manager), then:
npm run androidNote: First build takes 3-5 minutes.
Troubleshooting
iOS Issues
"No `Podfile' found"
Make sure you're in the
iosdirectory:cd ios && pod install
Build fails with signing errors
Open
ios/BurritoApp.xcworkspacein XcodeSelect the project → Signing & Capabilities
Select your development team
Simulator not launching
Open Xcode → Open Developer Tool → Simulator
Or run:
open -a Simulator
Android Issues
"SDK location not found"
Ensure
ANDROID_HOMEis set in your shell profileRun
source ~/.zshrcafter adding it
"No connected devices"
Launch an emulator from Android Studio Device Manager
Or connect a physical device with USB debugging enabled
Gradle build fails
Try:
cd android && ./gradlew clean && cd ..Then:
npm run android
Project structure
src/
├── config/
│ └── posthog.ts # PostHog client configuration
├── contexts/
│ └── AuthContext.tsx # Authentication context with PostHog integration
├── navigation/
│ └── RootNavigator.tsx # React Navigation stack navigator
├── screens/
│ ├── HomeScreen.tsx # Home/login screen
│ ├── BurritoScreen.tsx # Demo feature screen with event tracking
│ └── ProfileScreen.tsx # User profile with error tracking demo
├── services/
│ └── storage.ts # AsyncStorage wrapper for persistence
├── styles/
│ └── theme.ts # Shared style constants
└── types/
└── env.d.ts # Type declarations for environment variables
App.tsx # Root component with PostHogProvider
index.js # App entry point
.env # Environment variables (create from .env.example)
ios/ # Native iOS project (Xcode)
android/ # Native Android project (Android Studio)Key integration points
PostHog client setup (config/posthog.ts)
The PostHog client is configured with V4 SDK options. If no project token is provided, analytics are disabled gracefully:
import PostHog from 'posthog-react-native'
import Config from 'react-native-config'
const apiKey = Config.POSTHOG_PROJECT_TOKEN
const isPostHogConfigured = apiKey && apiKey !== 'phc_your_project_token_here'
export const posthog = new PostHog(apiKey || 'placeholder_key', {
host: Config.POSTHOG_HOST || 'https://us.i.posthog.com',
disabled: !isPostHogConfigured, // Disable if no project token
captureAppLifecycleEvents: true,
debug: __DEV__,
flushAt: 20,
flushInterval: 10000,
preloadFeatureFlags: true,
})Provider setup with React Navigation v7 (App.tsx)
For React Navigation v7, PostHogProvider must be placed inside NavigationContainer, and screen tracking must be done manually:
import { NavigationContainer, NavigationContainerRef } from '@react-navigation/native'
import { PostHogProvider } from 'posthog-react-native'
import { posthog } from './src/config/posthog'
export default function App() {
const navigationRef = useRef<NavigationContainerRef<RootStackParamList>>(null)
const routeNameRef = useRef<string | undefined>()
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
routeNameRef.current = navigationRef.current?.getCurrentRoute()?.name
}}
onStateChange={() => {
// Manual screen tracking for React Navigation v7
const previousRouteName = routeNameRef.current
const currentRouteName = navigationRef.current?.getCurrentRoute()?.name
if (previousRouteName !== currentRouteName && currentRouteName) {
posthog.screen(currentRouteName, {
previous_screen: previousRouteName,
})
}
routeNameRef.current = currentRouteName
}}
>
<PostHogProvider
client={posthog}
autocapture={{
captureScreens: false, // Disabled for React Navigation v7
captureTouches: true, // Enable touch event autocapture
propsToCapture: ['testID'],
}}
>
<AuthProvider>
<RootNavigator />
</AuthProvider>
</PostHogProvider>
</NavigationContainer>
)
}Autocapture
PostHog autocapture automatically tracks:
Touch events: When users interact with the screen
App lifecycle events: Application Installed, Updated, Opened, Became Active, Backgrounded
Use testID prop on components to help identify them in analytics:
<TouchableOpacity testID="consider-burrito-button" onPress={handlePress}>
<Text>Consider Burrito</Text>
</TouchableOpacity>User identification (contexts/AuthContext.tsx)
Use $set and $set_once for person properties:
import { usePostHog } from 'posthog-react-native'
const posthog = usePostHog()
// On login - identify with person properties
posthog.identify(username, {
$set: {
username: username,
},
$set_once: {
first_login_date: new Date().toISOString(),
},
})
// Capture login event
posthog.capture('user_logged_in', {
username: username,
is_new_user: isNewUser,
})
// On logout - reset clears distinct ID and anonymous ID
posthog.capture('user_logged_out')
posthog.reset()Event tracking (screens/BurritoScreen.tsx)
Capture custom events with properties:
import { usePostHog } from 'posthog-react-native'
const posthog = usePostHog()
// We recommend using a [object] [verb] format for event names
posthog.capture('burrito_considered', {
total_considerations: user.burritoConsiderations + 1,
username: user.username,
})Error tracking (screens/ProfileScreen.tsx)
Capture exceptions using the $exception event:
import { usePostHog } from 'posthog-react-native'
const posthog = usePostHog()
try {
throw new Error('Test error for PostHog error tracking')
} catch (err) {
posthog.capture('$exception', {
$exception_type: err.name,
$exception_message: err.message,
$exception_source: 'ProfileScreen',
$exception_stack_trace_raw: err.stack,
})
}Session persistence (services/storage.ts)
AsyncStorage replaces localStorage for persisting user sessions:
import AsyncStorage from '@react-native-async-storage/async-storage'
export const storage = {
getCurrentUser: async (): Promise<string | null> => {
return await AsyncStorage.getItem('currentUser')
},
setCurrentUser: async (username: string): Promise<void> => {
await AsyncStorage.setItem('currentUser', username)
},
saveUser: async (user: User): Promise<void> => {
const users = await storage.getUsers()
users[user.username] = user
await AsyncStorage.setItem('users', JSON.stringify(users))
},
}Learn more
tests/App.test.tsx
/**
* @format
*/
import React from 'react';
import ReactTestRenderer from 'react-test-renderer';
import App from '../App';
test('renders correctly', async () => {
await ReactTestRenderer.act(() => {
ReactTestRenderer.create(<App />);
});
});
.env.example
POSTHOG_PROJECT_TOKEN=phc_your_project_token_here
POSTHOG_HOST=https://us.i.posthog.com
.prettierrc.js
module.exports = {
arrowParens: 'avoid',
singleQuote: true,
trailingComma: 'all',
};
android/app/debug.keystore
���� androiddebugkey CJ��� 0��0
+* ��N���O�J�`>���X'����_���ȏ�R9���,xJ'K~\j��:ز��}�U)Q]"���ա!� Ȉ��Ù��F�5�H�x�A�\�P�)��@�I�s�d��>�2#m�י�j/8p��","ȁ��|\����1e�7�!����h(����.�Fi5��o��ung�*�!�����vF��֪�Sb!��T��4�
�P
<G�̑�8���(��է!Zd"�{�k���'_+ �k��5o�>9�R.+4�/w3Y�s�By�������0(J�)pB�g̝��R�]�hT.?�0������kGg�=�/���� ^Q����".O�Qŗ���Q���Yg+8��f�%� �"`�Vf�b���M�6hW�q�t���[x�Ӏ��%\l���XV���u}:�9��'+N��7:z\��4�#��
��A�G���ݘLJad��ɓ�����{tbP�ў�lʉD}�I����m;�Ɉ#�t�6G�;!w��b@�xf)�G�EA�5X8 �sE_?/f��)��y�#��~�EZiW��L��mj��9)��LpoBI@f�]u�C����8g1B4���9�����b,���,b� �;�i���� �#���^#�d�ˢ���~�<w%JE��V�1d���/��=��Z�o�l���JC2��85�%8j�o��U�)����-nE}1(���%���01� -!I��Zz�g�l5����V�@v����>��x�VwLw_���N���o�i7E�/�(���f�0ڸl��ۅl��On�cѾ�d8�,J�&N��Ih��\pM^���{�z��T�Z�ڳ�r�u�(���3r�<��Y����K=��V�E�o�e��udz�z�"d#x�e�{o����\5�o�u��i�nvW��@%��9z��C�C:���mNA��8Z�zI��f�S�(ӝ{r292�p�{�pO') ��m5V�L��[c�ՒTd���
'�� p>*�R��0>NH��c���'K���dp�Z�kl�=NmKW�ȧ��)�9���ɴ@:�
�l�c���~��������GF�K�`�� ����|���=����3P*�.��\vUԑd�����|��H���x��2����p�Z��g��E�ƈ#f�rK����F��D8�"�
V)�n|���ʴ�1�(�o�$J����a��\sݦ8�$^@$�Q�.�vK��D� e�/�������QG��
˺��s����Y�q X.509 0�{0�c�#.�b0
*�H��
0m10 UUS10UUnknown10UUnknown10U
Unknown10UAndroid10U
Android Debug0
131231223504Z20520430223504Z0m10 UUS10UUnknown10UUnknown10U
Unknown10UAndroid10U
Android Debug0�"0
*�H��
� 0�
� ��n &�l�Dx�%�
[��w��zg�}��?�^�SkX��6��gp��5��q$����v�B�����/��4��X�Z[�H7�Wk�X���3�=!�)6�P���9�O�ٵa�WӈEI,Ժ��A_���u�si��>��W���@ُ-���'