mixpanel-react-native 3.1.2 → 3.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/.claude/settings.local.json +12 -1
  2. package/.github/dependabot.yml +7 -0
  3. package/.github/workflows/node.js.yml +24 -1
  4. package/.vscode/settings.json +2 -1
  5. package/MixpanelReactNative.podspec +1 -1
  6. package/Samples/MixpanelExample/ios/MixpanelExample.xcworkspace/contents.xcworkspacedata +10 -0
  7. package/Samples/MixpanelExample/ios/Podfile.lock +1996 -0
  8. package/Samples/MixpanelStarter/.bundle/config +2 -0
  9. package/Samples/MixpanelStarter/.env.example +4 -0
  10. package/Samples/MixpanelStarter/.eslintrc.js +4 -0
  11. package/Samples/MixpanelStarter/.prettierrc.js +5 -0
  12. package/Samples/MixpanelStarter/.watchmanconfig +1 -0
  13. package/Samples/MixpanelStarter/App.tsx +10 -0
  14. package/Samples/MixpanelStarter/CLAUDE.md +538 -0
  15. package/Samples/MixpanelStarter/Gemfile +16 -0
  16. package/Samples/MixpanelStarter/INTEGRATION_GUIDE.md +606 -0
  17. package/Samples/MixpanelStarter/README.md +406 -0
  18. package/Samples/MixpanelStarter/__tests__/MixpanelContext.test.tsx +63 -0
  19. package/Samples/MixpanelStarter/android/app/build.gradle +119 -0
  20. package/Samples/MixpanelStarter/android/app/debug.keystore +0 -0
  21. package/Samples/MixpanelStarter/android/app/proguard-rules.pro +10 -0
  22. package/Samples/MixpanelStarter/android/app/src/main/AndroidManifest.xml +27 -0
  23. package/Samples/MixpanelStarter/android/app/src/main/java/com/mixpanelstarter/MainActivity.kt +22 -0
  24. package/Samples/MixpanelStarter/android/app/src/main/java/com/mixpanelstarter/MainApplication.kt +27 -0
  25. package/Samples/MixpanelStarter/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  26. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  27. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  28. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  29. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  30. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  31. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  32. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  33. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  34. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  35. package/Samples/MixpanelStarter/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  36. package/Samples/MixpanelStarter/android/app/src/main/res/values/strings.xml +3 -0
  37. package/Samples/MixpanelStarter/android/app/src/main/res/values/styles.xml +9 -0
  38. package/Samples/MixpanelStarter/android/build.gradle +21 -0
  39. package/Samples/MixpanelStarter/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  40. package/Samples/MixpanelStarter/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  41. package/Samples/MixpanelStarter/android/gradle.properties +44 -0
  42. package/Samples/MixpanelStarter/android/gradlew +251 -0
  43. package/Samples/MixpanelStarter/android/gradlew.bat +99 -0
  44. package/Samples/MixpanelStarter/android/settings.gradle +6 -0
  45. package/Samples/MixpanelStarter/app.json +4 -0
  46. package/Samples/MixpanelStarter/babel.config.js +14 -0
  47. package/Samples/MixpanelStarter/index.js +9 -0
  48. package/Samples/MixpanelStarter/ios/.xcode.env +11 -0
  49. package/Samples/MixpanelStarter/ios/MixpanelStarter/AppDelegate.swift +48 -0
  50. package/Samples/MixpanelStarter/ios/MixpanelStarter/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  51. package/Samples/MixpanelStarter/ios/MixpanelStarter/Images.xcassets/Contents.json +6 -0
  52. package/Samples/MixpanelStarter/ios/MixpanelStarter/Info.plist +55 -0
  53. package/Samples/MixpanelStarter/ios/MixpanelStarter/LaunchScreen.storyboard +47 -0
  54. package/Samples/MixpanelStarter/ios/MixpanelStarter/PrivacyInfo.xcprivacy +38 -0
  55. package/Samples/MixpanelStarter/ios/MixpanelStarter.xcodeproj/project.pbxproj +482 -0
  56. package/Samples/MixpanelStarter/ios/MixpanelStarter.xcodeproj/xcshareddata/xcschemes/MixpanelStarter.xcscheme +88 -0
  57. package/Samples/MixpanelStarter/ios/MixpanelStarter.xcworkspace/contents.xcworkspacedata +10 -0
  58. package/Samples/MixpanelStarter/ios/Podfile +34 -0
  59. package/Samples/MixpanelStarter/ios/Podfile.lock +2839 -0
  60. package/Samples/MixpanelStarter/jest.config.js +3 -0
  61. package/Samples/MixpanelStarter/metro.config.js +42 -0
  62. package/Samples/MixpanelStarter/package-lock.json +12141 -0
  63. package/Samples/MixpanelStarter/package.json +51 -0
  64. package/Samples/MixpanelStarter/src/@types/env.d.ts +3 -0
  65. package/Samples/MixpanelStarter/src/App.tsx +83 -0
  66. package/Samples/MixpanelStarter/src/components/ActionButton.tsx +92 -0
  67. package/Samples/MixpanelStarter/src/components/ErrorBoundary.tsx +81 -0
  68. package/Samples/MixpanelStarter/src/components/EventTrackingLog.tsx +163 -0
  69. package/Samples/MixpanelStarter/src/components/FlagCard.tsx +199 -0
  70. package/Samples/MixpanelStarter/src/components/InfoCard.tsx +77 -0
  71. package/Samples/MixpanelStarter/src/components/TestResultDisplay.tsx +181 -0
  72. package/Samples/MixpanelStarter/src/constants/tracking.ts +77 -0
  73. package/Samples/MixpanelStarter/src/contexts/MixpanelContext.tsx +159 -0
  74. package/Samples/MixpanelStarter/src/screens/FeatureFlagsScreen.tsx +1011 -0
  75. package/Samples/MixpanelStarter/src/screens/HomeScreen.tsx +307 -0
  76. package/Samples/MixpanelStarter/src/screens/OnboardingScreen.tsx +253 -0
  77. package/Samples/MixpanelStarter/src/screens/SettingsScreen.tsx +316 -0
  78. package/Samples/MixpanelStarter/src/types/flags.types.ts +42 -0
  79. package/Samples/MixpanelStarter/src/types/mixpanel.types.ts +26 -0
  80. package/Samples/MixpanelStarter/tsconfig.json +13 -0
  81. package/__tests__/flags.test.js +730 -0
  82. package/__tests__/index.test.js +7 -3
  83. package/__tests__/jest_setup.js +18 -0
  84. package/android/build.gradle +1 -1
  85. package/android/src/main/java/com/mixpanel/reactnative/MixpanelReactNativeModule.java +272 -2
  86. package/index.d.ts +64 -1
  87. package/index.js +42 -3
  88. package/ios/MixpanelReactNative.m +19 -1
  89. package/ios/MixpanelReactNative.swift +183 -5
  90. package/javascript/mixpanel-flags-js.js +463 -0
  91. package/javascript/mixpanel-flags.js +290 -0
  92. package/javascript/mixpanel-main.js +13 -1
  93. package/package.json +2 -2
@@ -0,0 +1,2 @@
1
+ BUNDLE_PATH: "vendor/bundle"
2
+ BUNDLE_FORCE_RUBY_PLATFORM: 1
@@ -0,0 +1,4 @@
1
+ # Mixpanel Configuration
2
+ # Get your token from: https://mixpanel.com/project/YOUR_PROJECT_ID/settings#project
3
+
4
+ MIXPANEL_TOKEN="YOUR_MIXPANEL_PROJECT_TOKEN"
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: '@react-native',
4
+ };
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ arrowParens: 'avoid',
3
+ singleQuote: true,
4
+ trailingComma: 'all',
5
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * MixpanelStarter - Sample React Native App
3
+ * Demonstrates Mixpanel SDK integration with modern patterns
4
+ *
5
+ * @format
6
+ */
7
+
8
+ import App from './src/App';
9
+
10
+ export default App;
@@ -0,0 +1,538 @@
1
+ # CLAUDE.md - MixpanelStarter Sample App
2
+
3
+ This file provides guidance to Claude Code when working with the MixpanelStarter sample application.
4
+
5
+ ## Project Overview
6
+
7
+ **Purpose**: Modern, production-ready React Native sample app demonstrating Mixpanel SDK integration with TypeScript, Context API, and best practices.
8
+
9
+ **Target Audience**: Developers learning to integrate Mixpanel into their React Native apps.
10
+
11
+ **Positioning**: Bridges the gap between SimpleMixpanel (too basic) and MixpanelDemo (too complex), demonstrating 80% of common use cases.
12
+
13
+ ## Quick Reference
14
+
15
+ ### Tech Stack
16
+ - **React Native**: 0.82.1
17
+ - **React**: 19.1.1
18
+ - **TypeScript**: Strict mode enabled
19
+ - **Navigation**: React Navigation 7.x with bottom tabs
20
+ - **State Management**: Context API pattern
21
+ - **Testing**: Jest with React Native Testing Library
22
+
23
+ ### Key Dependencies
24
+ - `mixpanel-react-native` - Main SDK (file:../..)
25
+ - `@react-native-async-storage/async-storage` - Required for Mixpanel
26
+ - `@react-navigation/native` + `@react-navigation/bottom-tabs` - Navigation
27
+ - `react-native-dotenv` - Environment variables
28
+
29
+ ## Commands
30
+
31
+ ### Development
32
+ ```bash
33
+ # Install dependencies
34
+ npm install
35
+ cd ios && pod install && cd ..
36
+
37
+ # Run app
38
+ npm run ios # iOS simulator
39
+ npm run android # Android emulator
40
+ npm start # Start Metro bundler
41
+
42
+ # Testing
43
+ npm test # Run Jest tests
44
+ npm test -- --coverage # With coverage
45
+ npx tsc --noEmit # TypeScript compilation check
46
+
47
+ # Linting
48
+ npm run lint # Run ESLint
49
+ ```
50
+
51
+ ### Environment Setup
52
+ ```bash
53
+ # Create environment file
54
+ cp .env.example .env
55
+ # Edit .env and set: MIXPANEL_TOKEN=your_token_here
56
+ ```
57
+
58
+ ### Troubleshooting Commands
59
+ ```bash
60
+ # Clear Metro cache
61
+ npm start -- --reset-cache
62
+
63
+ # Clean iOS build
64
+ cd ios && xcodebuild clean && cd ..
65
+
66
+ # Clean Android build
67
+ cd android && ./gradlew clean && cd ..
68
+
69
+ # Reinstall dependencies
70
+ rm -rf node_modules && npm install
71
+ ```
72
+
73
+ ## Architecture & Code Patterns
74
+
75
+ ### Core Architecture Pattern: Context API + Custom Hook
76
+
77
+ ```typescript
78
+ // Provider wraps app root (src/App.tsx)
79
+ <MixpanelProvider token={token} trackAutomaticEvents={true}>
80
+ <NavigationContainer>
81
+ {/* app content */}
82
+ </NavigationContainer>
83
+ </MixpanelProvider>
84
+
85
+ // Hook usage in any component
86
+ const { mixpanel, isInitialized, track, identify } = useMixpanel();
87
+ ```
88
+
89
+ **Why Context API?**
90
+ - Simple, no boilerplate
91
+ - Built into React (widely understood)
92
+ - Sufficient for Mixpanel's simple state needs
93
+ - Avoids prop drilling
94
+
95
+ ### File Naming Conventions
96
+ - **Components**: PascalCase (ActionButton.tsx, InfoCard.tsx)
97
+ - **Screens**: PascalCase with "Screen" suffix (OnboardingScreen.tsx)
98
+ - **Contexts**: PascalCase with "Context" suffix (MixpanelContext.tsx)
99
+ - **Types**: kebab-case with .types.ts suffix (mixpanel.types.ts)
100
+ - **Constants**: kebab-case (tracking.ts)
101
+
102
+ ### Import Order Pattern
103
+ ```typescript
104
+ // 1. External libraries (React, React Native)
105
+ import React, {useState, useEffect} from 'react';
106
+ import {View, Text, StyleSheet} from 'react-native';
107
+
108
+ // 2. Navigation
109
+ import {NavigationContainer} from '@react-navigation/native';
110
+
111
+ // 3. Internal contexts/hooks
112
+ import {useMixpanel} from '../contexts/MixpanelContext';
113
+
114
+ // 4. Components
115
+ import {ActionButton} from '../components/ActionButton';
116
+
117
+ // 5. Constants/types
118
+ import {Events, Properties} from '../constants/tracking';
119
+ ```
120
+
121
+ ### Event Tracking Pattern
122
+ ```typescript
123
+ // Always use constants (prevents typos, enables autocomplete)
124
+ import {Events, Properties} from '../constants/tracking';
125
+
126
+ // Check initialization before tracking
127
+ if (isInitialized) {
128
+ track(Events.SCREEN_VIEWED, {
129
+ [Properties.SCREEN_NAME]: 'Home',
130
+ [Properties.TIMESTAMP]: new Date().toISOString(),
131
+ });
132
+ }
133
+
134
+ // Track on mount with useEffect
135
+ useEffect(() => {
136
+ if (isInitialized) {
137
+ track(Events.SCREEN_VIEWED, {...});
138
+ }
139
+ }, [isInitialized, track]);
140
+ ```
141
+
142
+ ### User Identification Pattern
143
+ ```typescript
144
+ // Complete signup flow (OnboardingScreen.tsx:52-90)
145
+ const previousId = await mixpanel.getDistinctId();
146
+ identify(userId); // Set new identity
147
+ await alias(userId, previousId); // Link anonymous events
148
+ mixpanel.getPeople().set({...}); // Set profile
149
+ mixpanel.getPeople().setOnce({...}); // Set immutable properties
150
+ track(Events.USER_SIGNED_UP, {...}); // Track event
151
+ ```
152
+
153
+ ### Privacy-Compliant Logout Pattern
154
+ ```typescript
155
+ // SettingsScreen.tsx demonstrates GDPR-compliant logout
156
+ track('User Logged Out', {...}); // Track before clearing
157
+ await flush(); // Ensure events sent
158
+ reset(); // Clear all data
159
+ ```
160
+
161
+ ## Project Structure
162
+
163
+ ```
164
+ MixpanelStarter/
165
+ ├── src/
166
+ │ ├── contexts/
167
+ │ │ └── MixpanelContext.tsx # Context provider + useMixpanel hook
168
+ │ ├── screens/ # 3 tab screens
169
+ │ │ ├── OnboardingScreen.tsx # User identification flow
170
+ │ │ ├── HomeScreen.tsx # Event tracking patterns
171
+ │ │ └── SettingsScreen.tsx # Privacy controls
172
+ │ ├── components/ # Reusable components
173
+ │ │ ├── ErrorBoundary.tsx # Error boundary wrapper
174
+ │ │ ├── ActionButton.tsx # Button with loading states
175
+ │ │ └── InfoCard.tsx # Key-value display card
176
+ │ ├── types/
177
+ │ │ └── mixpanel.types.ts # TypeScript interfaces
178
+ │ ├── constants/
179
+ │ │ └── tracking.ts # Event names & properties
180
+ │ ├── @types/
181
+ │ │ └── env.d.ts # Environment variable types
182
+ │ └── App.tsx # Navigation setup
183
+ ├── __tests__/
184
+ │ └── MixpanelContext.test.tsx # Context tests
185
+ ├── ios/ # iOS native code
186
+ ├── android/ # Android native code
187
+ ├── .env.example # Environment template
188
+ ├── README.md # User-facing documentation
189
+ └── INTEGRATION_GUIDE.md # Step-by-step integration guide
190
+ ```
191
+
192
+ ### File Responsibilities
193
+
194
+ **MixpanelContext.tsx** (src/contexts/)
195
+ - Initializes Mixpanel SDK on mount
196
+ - Sets default super properties (app version, platform, environment)
197
+ - Provides convenience wrapper methods (track, identify, alias, reset, flush)
198
+ - Manages loading/error states
199
+ - Exports useMixpanel hook
200
+
201
+ **OnboardingScreen.tsx** (src/screens/)
202
+ - Demonstrates: identify(), alias(), getPeople().set(), setOnce()
203
+ - Shows anonymous-to-identified user flow
204
+ - Displays current distinct ID
205
+ - Guest mode vs signup comparison
206
+
207
+ **HomeScreen.tsx** (src/screens/)
208
+ - Demonstrates: track(), timeEvent(), registerSuperProperties()
209
+ - Event tracking with rich properties
210
+ - Timed events (video start/complete)
211
+ - Dynamic super properties (dark mode, notifications)
212
+ - Displays current super properties
213
+
214
+ **SettingsScreen.tsx** (src/screens/)
215
+ - Demonstrates: optIn/OutTracking(), reset(), flush(), hasOptedOutTracking()
216
+ - GDPR compliance controls
217
+ - Data management (reset all data)
218
+ - Manual flush for testing
219
+ - SDK information display
220
+
221
+ **tracking.ts** (src/constants/)
222
+ - Centralized event names (Events object)
223
+ - Property names (Properties object)
224
+ - Super property keys (SuperProperties object)
225
+ - All constants are `as const` for type safety
226
+
227
+ ## Key Concepts Demonstrated
228
+
229
+ ### 1. Initialization Lifecycle
230
+ ```typescript
231
+ // Context handles initialization automatically
232
+ useEffect(() => {
233
+ const initMixpanel = async () => {
234
+ const instance = new Mixpanel(token, trackAutomaticEvents, useNative);
235
+ await instance.init();
236
+ instance.registerSuperProperties({...});
237
+ setMixpanel(instance);
238
+ setIsInitialized(true);
239
+ };
240
+ initMixpanel();
241
+ }, [token]);
242
+ ```
243
+
244
+ ### 2. Loading State Management
245
+ ```typescript
246
+ // Components can check initialization state
247
+ const { isInitialized, isLoading, error } = useMixpanel();
248
+
249
+ // Disable buttons until ready
250
+ <ActionButton
251
+ disabled={!isInitialized}
252
+ onPress={handleAction}
253
+ />
254
+ ```
255
+
256
+ ### 3. Error Handling
257
+ ```typescript
258
+ // Context catches initialization errors
259
+ try {
260
+ await instance.init();
261
+ } catch (err) {
262
+ setError(err instanceof Error ? err : new Error(String(err)));
263
+ console.error('Failed to initialize Mixpanel:', error);
264
+ }
265
+
266
+ // ErrorBoundary catches React errors
267
+ <ErrorBoundary>
268
+ <MixpanelProvider>
269
+ {/* app */}
270
+ </MixpanelProvider>
271
+ </ErrorBoundary>
272
+ ```
273
+
274
+ ### 4. TypeScript Strict Mode
275
+ - All files compile without errors
276
+ - Proper typing for all props and state
277
+ - Event/property names are type-safe constants
278
+ - No `any` types except in Record<string, any> for event properties
279
+
280
+ ### 5. Educational Components
281
+ Every screen includes an InfoCard titled "What's Happening?" that explains:
282
+ - Which SDK methods are being used
283
+ - Why you'd use this pattern
284
+ - What data is being sent
285
+
286
+ ## Common Modifications
287
+
288
+ ### Adding a New Event
289
+
290
+ 1. **Define constant** (src/constants/tracking.ts):
291
+ ```typescript
292
+ export const Events = {
293
+ // ... existing events
294
+ FEATURE_USED: 'Feature Used',
295
+ };
296
+ ```
297
+
298
+ 2. **Track in component**:
299
+ ```typescript
300
+ const handleFeatureUse = () => {
301
+ track(Events.FEATURE_USED, {
302
+ feature_name: 'search',
303
+ timestamp: new Date().toISOString(),
304
+ });
305
+ };
306
+ ```
307
+
308
+ ### Adding a New Screen
309
+
310
+ 1. **Create screen file** (src/screens/NewScreen.tsx):
311
+ ```typescript
312
+ import {useMixpanel} from '../contexts/MixpanelContext';
313
+ import {Events, Properties} from '../constants/tracking';
314
+
315
+ export const NewScreen = () => {
316
+ const {track, isInitialized} = useMixpanel();
317
+
318
+ useEffect(() => {
319
+ if (isInitialized) {
320
+ track(Events.SCREEN_VIEWED, {
321
+ [Properties.SCREEN_NAME]: 'NewScreen',
322
+ });
323
+ }
324
+ }, [isInitialized, track]);
325
+
326
+ // ... component logic
327
+ };
328
+ ```
329
+
330
+ 2. **Add to navigation** (src/App.tsx):
331
+ ```typescript
332
+ <Tab.Screen
333
+ name="New"
334
+ component={NewScreen}
335
+ options={{
336
+ tabBarLabel: 'New',
337
+ tabBarIcon: ({color}) => <Text style={{fontSize: 20, color}}>🎯</Text>,
338
+ }}
339
+ />
340
+ ```
341
+
342
+ ### Changing Mixpanel Configuration
343
+
344
+ **In MixpanelProvider** (src/contexts/MixpanelContext.tsx):
345
+ ```typescript
346
+ // Change automatic event tracking
347
+ trackAutomaticEvents={false}
348
+
349
+ // Change native/JS mode
350
+ useNative={false} // Forces JavaScript implementation
351
+
352
+ // Modify default super properties
353
+ instance.registerSuperProperties({
354
+ [SuperProperties.APP_VERSION]: '2.0.0', // Update version
355
+ 'Custom Property': 'value', // Add custom property
356
+ });
357
+ ```
358
+
359
+ ## Testing Guidelines
360
+
361
+ ### Running Tests
362
+ ```bash
363
+ npm test # Run all tests
364
+ npm test -- --coverage # With coverage report
365
+ npm test -- --watch # Watch mode
366
+ ```
367
+
368
+ ### Test Structure
369
+ - **Unit tests**: Components and contexts in isolation
370
+ - **Mock Mixpanel SDK**: Already configured in MixpanelContext.test.tsx
371
+ - **Test initialization**: Verify loading → initialized state transition
372
+ - **Test error handling**: Provider catches and exposes errors
373
+
374
+ ### Writing New Tests
375
+ ```typescript
376
+ // Mock Mixpanel SDK
377
+ jest.mock('mixpanel-react-native', () => ({
378
+ Mixpanel: jest.fn().mockImplementation(() => ({
379
+ init: jest.fn().mockResolvedValue(undefined),
380
+ track: jest.fn(),
381
+ // ... other methods
382
+ })),
383
+ }));
384
+
385
+ // Test component with context
386
+ render(
387
+ <MixpanelProvider token="test-token">
388
+ <YourComponent />
389
+ </MixpanelProvider>
390
+ );
391
+ ```
392
+
393
+ ## TypeScript Configuration
394
+
395
+ ### Strict Mode Enabled
396
+ ```json
397
+ {
398
+ "compilerOptions": {
399
+ "strict": true, // All strict checks enabled
400
+ "typeRoots": ["./node_modules/@types", "./src/@types"]
401
+ }
402
+ }
403
+ ```
404
+
405
+ ### Type Checking
406
+ ```bash
407
+ npx tsc --noEmit # Check types without emitting files
408
+ ```
409
+
410
+ ### Common Type Issues
411
+ - **Environment variables**: Defined in src/@types/env.d.ts
412
+ - **Mixpanel instance**: Can be null before initialization (check isInitialized)
413
+ - **Async methods**: alias() and flush() return Promise<void>
414
+
415
+ ## Debugging
416
+
417
+ ### Enable Logging
418
+ Logging is automatically enabled in development (`__DEV__`):
419
+ ```typescript
420
+ if (__DEV__) {
421
+ instance.setLoggingEnabled(true);
422
+ }
423
+ ```
424
+
425
+ ### Console Output
426
+ Look for `[Mixpanel]` prefixed logs:
427
+ - Event tracking confirmations
428
+ - Network requests
429
+ - Error messages
430
+ - Queue status
431
+
432
+ ### Verify Events
433
+ 1. **Console**: Check for `[Mixpanel]` logs
434
+ 2. **Network**: Use React Native Debugger to see network requests
435
+ 3. **Dashboard**: Events appear in Mixpanel Live View (may take 1-2 minutes)
436
+ 4. **Distinct ID**: Call `await mixpanel.getDistinctId()` to verify initialization
437
+
438
+ ### Common Issues
439
+
440
+ **Events not tracked?**
441
+ - Check `isInitialized` is true
442
+ - Verify token is set correctly
443
+ - Check opt-out status: `await hasOptedOutTracking()`
444
+ - Manually flush: `await flush()`
445
+
446
+ **TypeScript errors?**
447
+ - Clear Metro cache: `npm start -- --reset-cache`
448
+ - Verify all dependencies installed: `npm install`
449
+ - Check tsconfig.json is correct
450
+
451
+ **Build errors?**
452
+ - iOS: `cd ios && pod install && cd ..`
453
+ - Android: `cd android && ./gradlew clean && cd ..`
454
+ - Clear node_modules: `rm -rf node_modules && npm install`
455
+
456
+ ## Best Practices for Modifications
457
+
458
+ ### DO:
459
+ ✅ Use constants for event/property names
460
+ ✅ Check `isInitialized` before tracking
461
+ ✅ Include timestamps in event properties
462
+ ✅ Add "What's Happening?" explanations for new features
463
+ ✅ Follow existing file structure and naming conventions
464
+ ✅ Update TypeScript types when adding new interfaces
465
+ ✅ Test on both iOS and Android
466
+ ✅ Keep Context API pattern for Mixpanel access
467
+
468
+ ### DON'T:
469
+ ❌ Hardcode event names (use constants)
470
+ ❌ Track before initialization
471
+ ❌ Use `any` type (use strict TypeScript)
472
+ ❌ Skip error handling
473
+ ❌ Track PII without user consent
474
+ ❌ Over-track (every render/state change)
475
+ ❌ Mix navigation patterns (stick to bottom tabs)
476
+
477
+ ## Educational Purpose
478
+
479
+ This sample app is designed to teach, not just demonstrate. When making changes:
480
+
481
+ 1. **Preserve educational value**: Keep "What's Happening?" cards updated
482
+ 2. **Maintain simplicity**: This bridges simple→complex, don't overcomplicate
483
+ 3. **Document patterns**: Add comments explaining WHY, not just WHAT
484
+ 4. **Keep it copy-pasteable**: Developers should be able to copy patterns directly
485
+
486
+ ## Integration with Parent SDK
487
+
488
+ This sample lives at: `Samples/MixpanelStarter/`
489
+
490
+ **SDK dependency**: Uses `file:../..` to reference parent mixpanel-react-native package
491
+
492
+ **When SDK changes**:
493
+ ```bash
494
+ cd Samples/MixpanelStarter
495
+ rm -rf node_modules
496
+ npm install # Re-links to parent SDK
497
+ ```
498
+
499
+ ## Documentation Maintenance
500
+
501
+ ### When to Update Docs
502
+
503
+ **README.md**: User-facing changes (new features, setup steps, troubleshooting)
504
+ **INTEGRATION_GUIDE.md**: Integration patterns, API changes, best practices
505
+ **CLAUDE.md**: Architecture changes, new patterns, file structure updates
506
+
507
+ ### Documentation Standards
508
+ - Keep examples up-to-date with actual code
509
+ - Include both "why" and "how" explanations
510
+ - Use code snippets from real files (with file paths)
511
+ - Maintain consistent formatting and style
512
+
513
+ ## Version Information
514
+
515
+ **Created**: 2025
516
+ **React Native Version**: 0.82.1
517
+ **Mixpanel SDK**: 3.1.2
518
+ **Target RN Version**: 0.70+
519
+
520
+ ## AI Assistant Notes
521
+
522
+ When working with this codebase:
523
+
524
+ 1. **Preserve the educational mission**: This is a learning tool, not just a demo
525
+ 2. **Maintain Context API pattern**: Don't switch to Redux/MobX/etc
526
+ 3. **Keep TypeScript strict**: No `any` types, proper inference
527
+ 4. **Follow existing patterns**: File naming, import order, component structure
528
+ 5. **Test changes**: Run `npm test` and `npx tsc --noEmit` before completing
529
+ 6. **Update documentation**: README, INTEGRATION_GUIDE, and CLAUDE.md as needed
530
+
531
+ ## Resources
532
+
533
+ - **Parent SDK**: `../../` (mixpanel-react-native)
534
+ - **Parent CLAUDE.md**: `../../CLAUDE.md`
535
+ - **Mixpanel Docs**: https://docs.mixpanel.com/docs/tracking/advanced/react-native
536
+ - **React Navigation**: https://reactnavigation.org/
537
+
538
+ Last updated: 2025-05-11
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4
+ ruby ">= 2.6.10"
5
+
6
+ # Exclude problematic versions of cocoapods and activesupport that causes build failures.
7
+ gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8
+ gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9
+ gem 'xcodeproj', '< 1.26.0'
10
+ gem 'concurrent-ruby', '< 1.3.4'
11
+
12
+ # Ruby 3.4.0 has removed some libraries from the standard library.
13
+ gem 'bigdecimal'
14
+ gem 'logger'
15
+ gem 'benchmark'
16
+ gem 'mutex_m'