SDKsAnalytics
Analytics are your feedback loop.
This boilerplate ships with a single analytics API that can send events to:
- Amplitude (via
@amplitude/analytics-react-native) - PostHog (via
posthog-react-native)
Both providers are optional: if keys are missing, analytics become a no-op (no crashes).
Where the code lives
- Public API:
src/shared/hooks/use-analytics.tsx(AnalyticsProvider+useAnalytics()hook) - Amplitude wrapper:
src/shared/libs/amplitude.ts - PostHog wrapper:
src/shared/libs/posthog.ts - Provider mounting:
src/shared/hooks/providers.tsx(wraps app, creates stable anonymoususerIdin SecureStore)
1) Environment variables
Add to .env (or EAS secrets):
Amplitude: EXPO_PUBLIC_AMPLITUDE_IOS_API_KEY, EXPO_PUBLIC_AMPLITUDE_ANDROID_API_KEY
Reference: Amplitude React Native SDK
PostHog: EXPO_PUBLIC_POSTHOG_IOS_API_KEY, EXPO_PUBLIC_POSTHOG_ANDROID_API_KEY
Reference: PostHog React Native
2) Identity
Identity comes from useUserStore().userId.
On first launch, providers.tsx generates an anonymous UUID and persists it in SecureStore (key: analytics_anon_id). That ID becomes your default analytics user id.
When userId changes, AnalyticsProvider automatically:
- calls
setAmplitudeUserId(userId)(or resets ifnull) - calls
setPostHogUserId(userId)(or resets ifnull)
3) Tracking events
tsx
Property sanitization: use-analytics.tsx drops undefined, functions, and nested objects; converts dates to ISO strings; allows strings, numbers, booleans, null. Keep properties flat + primitive.
4) Identifying users
Call identifyUser when you learn stable traits (e.g., onboarding completion):
tsx
- Amplitude: maps to
Identify()with.set(k, v) - PostHog: maps to
identify(userId, props)(orregister(props)if no userId)
5) Best practices
Keep analytics calls:
- In screens / orchestration layers (e.g.,
src/app/...or feature screens) - Out of shared UI components (
src/shared/ui/*should remain "dumb UI")
If you need analytics inside a feature, prefer calling it from the feature screen or a feature hook (not from low-level UI primitives).
