unified-analytics-mohit 1.0.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.
- package/README.md +662 -0
- package/docs/COUNTLY.md +420 -0
- package/docs/POSTHOG.md +522 -0
- package/index.js +21 -0
- package/package.json +39 -0
- package/src/UnifiedAnalytics.js +595 -0
- package/src/context/AnalyticsProvider.js +72 -0
- package/src/hooks/useAnalytics.js +179 -0
- package/src/index.js +27 -0
- package/src/platform.js +69 -0
- package/src/providers/BaseProvider.js +81 -0
- package/src/providers/CountlyProvider.js +182 -0
- package/src/providers/CountlyProvider.native.js +497 -0
- package/src/providers/CountlyProvider.web.js +533 -0
- package/src/providers/PostHogProvider.js +214 -0
- package/src/providers/PostHogProvider.native.js +515 -0
- package/src/providers/PostHogProvider.web.js +563 -0
- package/src/providers/index.js +3 -0
- package/src/utils/helpers.js +117 -0
package/README.md
ADDED
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
# Unified Analytics Library
|
|
2
|
+
|
|
3
|
+
A **pure facade layer** for analytics that provides a single, unified API across multiple analytics providers (Countly, PostHog) on both **React Native** and **Web** (React.js / Next.js).
|
|
4
|
+
|
|
5
|
+
## Core Philosophy
|
|
6
|
+
|
|
7
|
+
**One API to rule them all.** The app code uses only unified methods - no provider-specific code required. The library internally maps to the appropriate provider implementations with graceful degradation when features aren't supported.
|
|
8
|
+
|
|
9
|
+
## Key Features
|
|
10
|
+
|
|
11
|
+
- **Pure Facade Pattern**: Single unified API, no provider-specific exposure
|
|
12
|
+
- **Cross-Platform**: Works on React Native and Web (React.js/Next.js)
|
|
13
|
+
- **Graceful Degradation**: Features return null/false when not supported instead of errors
|
|
14
|
+
- **Multi-Provider Support**: Use Countly, PostHog, or both simultaneously
|
|
15
|
+
- **React Hooks**: Easy integration with `useAnalytics()` hook
|
|
16
|
+
- **Zero Configuration**: Auto-detects platform, works with one or both providers
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
1. Copy this library to your project (e.g., `libs/unified-analytics`)
|
|
21
|
+
|
|
22
|
+
2. Install the provider SDK(s) you want to use:
|
|
23
|
+
|
|
24
|
+
**React Native:**
|
|
25
|
+
```bash
|
|
26
|
+
# For Countly
|
|
27
|
+
yarn add countly-sdk-react-native-bridge@^24.4.0
|
|
28
|
+
|
|
29
|
+
# For PostHog
|
|
30
|
+
yarn add posthog-react-native@^3.0.0
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Web (React.js / Next.js):**
|
|
35
|
+
```bash
|
|
36
|
+
# For Countly
|
|
37
|
+
yarn add countly-sdk-web
|
|
38
|
+
|
|
39
|
+
# For PostHog
|
|
40
|
+
yarn add posthog-js
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
### React Native Setup
|
|
46
|
+
|
|
47
|
+
#### 1. Initialize Analytics
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
// App.js
|
|
51
|
+
import { analytics, AnalyticsProvider } from './libs/unified-analytics';
|
|
52
|
+
|
|
53
|
+
await analytics.init({
|
|
54
|
+
platform: 'native', // optional, auto-detected
|
|
55
|
+
|
|
56
|
+
countly: {
|
|
57
|
+
serverUrl: 'https://your-countly-server.com',
|
|
58
|
+
appKey: 'your-app-key',
|
|
59
|
+
enableCrashReporting: true,
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
posthog: {
|
|
63
|
+
apiKey: 'phc_xxxxx',
|
|
64
|
+
enableSessionReplay: true,
|
|
65
|
+
captureNativeAppLifecycleEvents: true,
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
debug: __DEV__,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Wrap your app
|
|
72
|
+
export default function App() {
|
|
73
|
+
return (
|
|
74
|
+
<AnalyticsProvider>
|
|
75
|
+
<Navigation />
|
|
76
|
+
</AnalyticsProvider>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### 2. Setup Navigation Tracking (React Navigation)
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
import { analytics } from './libs/unified-analytics';
|
|
85
|
+
|
|
86
|
+
function App() {
|
|
87
|
+
const navigationRef = useRef();
|
|
88
|
+
|
|
89
|
+
const { onReady, onStateChange } = analytics.createNavigationHandlers(navigationRef);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<NavigationContainer
|
|
93
|
+
ref={navigationRef}
|
|
94
|
+
onReady={onReady}
|
|
95
|
+
onStateChange={onStateChange}
|
|
96
|
+
>
|
|
97
|
+
<Navigator />
|
|
98
|
+
</NavigationContainer>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### Web (Next.js) Setup
|
|
106
|
+
|
|
107
|
+
#### 1. Initialize Analytics
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
// _app.js or layout.js
|
|
111
|
+
import { analytics, AnalyticsProvider } from 'unified-analytics';
|
|
112
|
+
|
|
113
|
+
await analytics.init({
|
|
114
|
+
platform: 'web',
|
|
115
|
+
|
|
116
|
+
countly: {
|
|
117
|
+
serverUrl: 'https://your-countly-server.com',
|
|
118
|
+
appKey: 'your-web-app-key',
|
|
119
|
+
debug: process.env.NODE_ENV === 'development',
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
posthog: {
|
|
123
|
+
apiKey: 'phc_xxxxx',
|
|
124
|
+
host: 'https://us.i.posthog.com',
|
|
125
|
+
debug: process.env.NODE_ENV === 'development',
|
|
126
|
+
enableSessionReplay: true,
|
|
127
|
+
autocapture: {
|
|
128
|
+
captureClicks: true,
|
|
129
|
+
capturePageviews: false, // We handle this manually
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
debug: process.env.NODE_ENV === 'development',
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### 2. Setup Navigation Tracking
|
|
138
|
+
|
|
139
|
+
**Next.js Pages Router:**
|
|
140
|
+
```javascript
|
|
141
|
+
import Router from 'next/router';
|
|
142
|
+
import { analytics } from 'unified-analytics';
|
|
143
|
+
|
|
144
|
+
const { onRouteChange } = analytics.createWebNavigationHandlers();
|
|
145
|
+
Router.events.on('routeChangeComplete', onRouteChange);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Next.js App Router:**
|
|
149
|
+
```javascript
|
|
150
|
+
'use client';
|
|
151
|
+
import { usePathname } from 'next/navigation';
|
|
152
|
+
import { analytics } from 'unified-analytics';
|
|
153
|
+
import { useEffect, useRef } from 'react';
|
|
154
|
+
|
|
155
|
+
function NavigationTracker() {
|
|
156
|
+
const pathname = usePathname();
|
|
157
|
+
const handlersRef = useRef(analytics.createWebNavigationHandlers());
|
|
158
|
+
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
handlersRef.current.onRouteChange(pathname);
|
|
161
|
+
}, [pathname]);
|
|
162
|
+
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**React Router:**
|
|
168
|
+
```javascript
|
|
169
|
+
import { useLocation } from 'react-router-dom';
|
|
170
|
+
import { analytics } from 'unified-analytics';
|
|
171
|
+
import { useEffect, useRef } from 'react';
|
|
172
|
+
|
|
173
|
+
function NavigationTracker() {
|
|
174
|
+
const location = useLocation();
|
|
175
|
+
const handlersRef = useRef(analytics.createWebNavigationHandlers());
|
|
176
|
+
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
handlersRef.current.onRouteChange(location.pathname);
|
|
179
|
+
}, [location]);
|
|
180
|
+
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### 3. Use in Components (Same on Both Platforms)
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
import { useAnalytics } from 'unified-analytics';
|
|
191
|
+
|
|
192
|
+
function MyComponent() {
|
|
193
|
+
const {
|
|
194
|
+
trackEvent,
|
|
195
|
+
setGlobalProperties,
|
|
196
|
+
trackError,
|
|
197
|
+
getFeatureFlag,
|
|
198
|
+
} = useAnalytics();
|
|
199
|
+
|
|
200
|
+
const handleLogin = (user) => {
|
|
201
|
+
setGlobalProperties({
|
|
202
|
+
user_id: user.id,
|
|
203
|
+
role: user.role,
|
|
204
|
+
organization: user.org,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
trackEvent('login', { method: 'email' });
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const handleButtonClick = () => {
|
|
211
|
+
trackEvent('button_click', {
|
|
212
|
+
button: 'submit',
|
|
213
|
+
screen: 'Profile',
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const handleError = (error) => {
|
|
218
|
+
trackError(error, {
|
|
219
|
+
screen: 'Profile',
|
|
220
|
+
action: 'update_profile',
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const checkFeature = () => {
|
|
225
|
+
const isEnabled = getFeatureFlag('new_feature');
|
|
226
|
+
if (isEnabled) {
|
|
227
|
+
// Show new feature
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
return <Button onPress={handleButtonClick} title="Submit" />;
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Platform Configuration
|
|
238
|
+
|
|
239
|
+
### Platform Detection
|
|
240
|
+
|
|
241
|
+
The library auto-detects the platform, but you can explicitly set it:
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
analytics.init({
|
|
245
|
+
platform: 'native', // or 'web'
|
|
246
|
+
// ...
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Auto-detection logic:
|
|
251
|
+
- **Native**: `navigator.product === 'ReactNative'`
|
|
252
|
+
- **Web**: `typeof window !== 'undefined'` and not React Native
|
|
253
|
+
|
|
254
|
+
### Platform Utilities
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
import { setPlatform, getPlatform, isWeb, isNative } from 'unified-analytics';
|
|
258
|
+
|
|
259
|
+
console.log(getPlatform()); // 'web' or 'native'
|
|
260
|
+
console.log(isWeb()); // true/false
|
|
261
|
+
console.log(isNative()); // true/false
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Complete API Reference
|
|
267
|
+
|
|
268
|
+
### Core Methods
|
|
269
|
+
|
|
270
|
+
#### `trackEvent(name, properties)`
|
|
271
|
+
Track a custom event.
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
trackEvent('purchase', {
|
|
275
|
+
product_id: '123',
|
|
276
|
+
amount: 99.99,
|
|
277
|
+
currency: 'USD',
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Providers**: Countly, PostHog | **Platforms**: Native, Web
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
#### `trackView(viewName, properties)`
|
|
286
|
+
Track a screen/page view.
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
trackView('Profile', { user_type: 'premium' });
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Providers**: Countly, PostHog | **Platforms**: Native, Web
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
#### `identify(userId, properties)`
|
|
297
|
+
Identify a user.
|
|
298
|
+
|
|
299
|
+
```javascript
|
|
300
|
+
identify('user_123', {
|
|
301
|
+
email: 'user@example.com',
|
|
302
|
+
name: 'John Doe',
|
|
303
|
+
});
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Providers**: Countly, PostHog | **Platforms**: Native, Web
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
#### `setUserProperties(properties)`
|
|
311
|
+
Set/update user profile properties.
|
|
312
|
+
|
|
313
|
+
```javascript
|
|
314
|
+
setUserProperties({
|
|
315
|
+
plan: 'premium',
|
|
316
|
+
signup_date: '2024-01-15',
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Providers**: Countly, PostHog | **Platforms**: Native, Web
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
#### `reset()`
|
|
325
|
+
Logout/reset user session.
|
|
326
|
+
|
|
327
|
+
```javascript
|
|
328
|
+
reset();
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Providers**: Countly, PostHog | **Platforms**: Native, Web
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
### Global Properties (Unified)
|
|
336
|
+
|
|
337
|
+
Properties automatically included in **every** event.
|
|
338
|
+
|
|
339
|
+
#### `setGlobalProperties(properties)`
|
|
340
|
+
```javascript
|
|
341
|
+
setGlobalProperties({
|
|
342
|
+
user_id: '123',
|
|
343
|
+
role: 'admin',
|
|
344
|
+
app_version: '6.0.0',
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**Internal Mapping**:
|
|
349
|
+
- **Countly** -> `userContext` (custom merge on every event)
|
|
350
|
+
- **PostHog** -> `register()` (native super properties)
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
#### `getGlobalProperties()`
|
|
355
|
+
```javascript
|
|
356
|
+
const props = getGlobalProperties();
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
#### `clearGlobalProperties()`
|
|
362
|
+
```javascript
|
|
363
|
+
clearGlobalProperties();
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
#### `removeGlobalProperty(key)`
|
|
369
|
+
```javascript
|
|
370
|
+
removeGlobalProperty('user_id');
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
### Timed Events (Unified)
|
|
376
|
+
|
|
377
|
+
#### `startTimer(eventName)` / `endTimer(eventName, properties)`
|
|
378
|
+
```javascript
|
|
379
|
+
startTimer('page_load');
|
|
380
|
+
// ... later
|
|
381
|
+
endTimer('page_load', { page: 'dashboard' });
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Providers**: Countly (native), PostHog (graceful no-op)
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
### Error Tracking (Unified)
|
|
389
|
+
|
|
390
|
+
#### `trackError(error, metadata)`
|
|
391
|
+
```javascript
|
|
392
|
+
try {
|
|
393
|
+
await riskyOperation();
|
|
394
|
+
} catch (error) {
|
|
395
|
+
trackError(error, {
|
|
396
|
+
screen: 'Dashboard',
|
|
397
|
+
action: 'load_data',
|
|
398
|
+
fatal: false,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Internal Mapping**:
|
|
404
|
+
- **Countly** -> `trackError()` + `addCrashLog()`
|
|
405
|
+
- **PostHog** -> `capture('$exception')`
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
### Session Management
|
|
410
|
+
|
|
411
|
+
Sessions are **automatically managed** by the Countly SDK:
|
|
412
|
+
- **Web**: `Countly.track_sessions()` handles begin/end/update automatically based on page visibility
|
|
413
|
+
- **React Native**: The SDK automatically tracks sessions based on app foreground/background state
|
|
414
|
+
|
|
415
|
+
No manual session management is required. The `startSession()` and `endSession()` methods are deprecated no-ops kept for backward compatibility.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
### Feature Flags (Unified)
|
|
420
|
+
|
|
421
|
+
#### `getFeatureFlag(key)` / `isFeatureEnabled(key)` / `getAllFeatureFlags()`
|
|
422
|
+
```javascript
|
|
423
|
+
const flag = getFeatureFlag('new_ui');
|
|
424
|
+
const enabled = isFeatureEnabled('beta_features');
|
|
425
|
+
const allFlags = getAllFeatureFlags();
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Providers**: Countly (returns null/false/{}), PostHog (native)
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
### Navigation Handlers
|
|
433
|
+
|
|
434
|
+
#### `createNavigationHandlers(navigationRef)` - React Native
|
|
435
|
+
```javascript
|
|
436
|
+
const { onReady, onStateChange } = analytics.createNavigationHandlers(navigationRef);
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
#### `createWebNavigationHandlers()` - Web
|
|
440
|
+
```javascript
|
|
441
|
+
const { onRouteChange } = analytics.createWebNavigationHandlers();
|
|
442
|
+
onRouteChange('/dashboard'); // Call on route change
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
### Screen View Overrides
|
|
448
|
+
|
|
449
|
+
#### `setScreenViewOverride(screenName, customName)`
|
|
450
|
+
```javascript
|
|
451
|
+
setScreenViewOverride("Login", "Login - Email Entry");
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
#### `clearScreenViewOverride(screenName)`
|
|
455
|
+
```javascript
|
|
456
|
+
clearScreenViewOverride("Login");
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
### Screen View Tracking Control
|
|
462
|
+
|
|
463
|
+
Screen view tracking is enabled by default. You can disable it via config or at runtime.
|
|
464
|
+
|
|
465
|
+
#### Disable via config (at init)
|
|
466
|
+
```javascript
|
|
467
|
+
analytics.init({
|
|
468
|
+
platform: 'web',
|
|
469
|
+
trackScreenViews: false, // Disables all trackView calls
|
|
470
|
+
countly: { ... },
|
|
471
|
+
posthog: { ... },
|
|
472
|
+
})
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
#### `setTrackScreenViews(enabled)` - Toggle at runtime
|
|
476
|
+
```javascript
|
|
477
|
+
// Disable screen view tracking
|
|
478
|
+
analytics.setTrackScreenViews(false)
|
|
479
|
+
|
|
480
|
+
// Re-enable screen view tracking
|
|
481
|
+
analytics.setTrackScreenViews(true)
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
When disabled, both automatic navigation tracking (`createNavigationHandlers` / `createWebNavigationHandlers`) and manual `trackView()` calls are suppressed. Works on both Native and Web.
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
### Provider-Specific (Web Only)
|
|
489
|
+
|
|
490
|
+
These methods are available when using the Countly web provider:
|
|
491
|
+
|
|
492
|
+
```javascript
|
|
493
|
+
const { countly } = analytics;
|
|
494
|
+
countly?.trackScrolls(); // Automatic scroll depth tracking
|
|
495
|
+
countly?.trackLinks(); // Automatic link click tracking
|
|
496
|
+
countly?.trackForms(); // Automatic form submission tracking
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
## Configuration
|
|
502
|
+
|
|
503
|
+
### Full Configuration Options
|
|
504
|
+
|
|
505
|
+
```javascript
|
|
506
|
+
analytics.init({
|
|
507
|
+
// Platform ('native' | 'web') - auto-detected if omitted
|
|
508
|
+
platform: 'native',
|
|
509
|
+
|
|
510
|
+
// Countly Configuration
|
|
511
|
+
countly: {
|
|
512
|
+
serverUrl: string, // Required
|
|
513
|
+
appKey: string, // Required
|
|
514
|
+
debug: boolean,
|
|
515
|
+
enableCrashReporting: boolean,
|
|
516
|
+
requiresConsent: boolean, // GDPR
|
|
517
|
+
deviceId: string,
|
|
518
|
+
useTemporaryDeviceId: boolean,
|
|
519
|
+
location: {
|
|
520
|
+
countryCode: string, // ISO 3166-1 alpha-2
|
|
521
|
+
city: string,
|
|
522
|
+
gpsCoordinates: string, // 'latitude,longitude'
|
|
523
|
+
ipAddress: string,
|
|
524
|
+
},
|
|
525
|
+
disableLocation: boolean,
|
|
526
|
+
tamperingProtectionSalt: string,
|
|
527
|
+
},
|
|
528
|
+
|
|
529
|
+
// PostHog Configuration
|
|
530
|
+
posthog: {
|
|
531
|
+
apiKey: string, // Required
|
|
532
|
+
host: string, // Default: https://us.i.posthog.com
|
|
533
|
+
debug: boolean,
|
|
534
|
+
disabled: boolean,
|
|
535
|
+
|
|
536
|
+
// RN-only options
|
|
537
|
+
flushInterval: number, // Seconds, default: 30
|
|
538
|
+
flushAt: number, // Events, default: 20
|
|
539
|
+
captureNativeAppLifecycleEvents: boolean,
|
|
540
|
+
sessionReplay: {
|
|
541
|
+
maskAllTextInputs: boolean,
|
|
542
|
+
maskAllImages: boolean,
|
|
543
|
+
captureLog: boolean, // RN only
|
|
544
|
+
captureNetworkTelemetry: boolean, // RN only
|
|
545
|
+
androidDebouncerDelayMs: number, // RN only
|
|
546
|
+
iOSdebouncerDelayMs: number, // RN only
|
|
547
|
+
},
|
|
548
|
+
autocapture: {
|
|
549
|
+
captureTouches: boolean, // RN only
|
|
550
|
+
captureScreens: boolean, // RN only
|
|
551
|
+
captureClicks: boolean, // Web only
|
|
552
|
+
capturePageviews: boolean, // Web only
|
|
553
|
+
capturePageleave: boolean, // Web only
|
|
554
|
+
},
|
|
555
|
+
|
|
556
|
+
// Common options
|
|
557
|
+
enableSessionReplay: boolean,
|
|
558
|
+
featureFlagsRequestTimeoutMs: number,
|
|
559
|
+
bootstrap: {
|
|
560
|
+
distinctId: string,
|
|
561
|
+
featureFlags: object,
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
|
|
565
|
+
// Global
|
|
566
|
+
debug: boolean,
|
|
567
|
+
trackScreenViews: boolean, // Default: true. Set false to disable all screen/page view tracking
|
|
568
|
+
});
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## Architecture
|
|
574
|
+
|
|
575
|
+
### Factory Pattern
|
|
576
|
+
|
|
577
|
+
Each provider uses a factory/proxy pattern:
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
CountlyProvider.js (factory)
|
|
581
|
+
├── CountlyProvider.native.js (React Native - uses countly-sdk-react-native-bridge)
|
|
582
|
+
└── CountlyProvider.web.js (Web - uses countly-sdk-web)
|
|
583
|
+
|
|
584
|
+
PostHogProvider.js (factory)
|
|
585
|
+
├── PostHogProvider.native.js (React Native - uses posthog-react-native)
|
|
586
|
+
└── PostHogProvider.web.js (Web - uses posthog-js)
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
The factory detects the platform and dynamically imports the correct implementation. The public API is identical across platforms.
|
|
590
|
+
|
|
591
|
+
### Feature Support Matrix
|
|
592
|
+
|
|
593
|
+
| Feature | Countly | PostHog | Platform |
|
|
594
|
+
|---------|---------|---------|----------|
|
|
595
|
+
| trackEvent | Native | Native | Both |
|
|
596
|
+
| trackView | Native | Native | Both |
|
|
597
|
+
| setGlobalProperties | Custom (userContext) | Native (register) | Both |
|
|
598
|
+
| startTimer/endTimer | Native | No-op | Both |
|
|
599
|
+
| trackError | Native | Native (via $exception) | Both |
|
|
600
|
+
| Feature Flags | Returns null | Native | Both |
|
|
601
|
+
| Session Management | Auto-managed | Auto-managed | Both |
|
|
602
|
+
| Session Recording | N/A | Native | Both |
|
|
603
|
+
| trackScrolls/Links/Forms | Native | N/A | Web only |
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
## Usage Patterns
|
|
608
|
+
|
|
609
|
+
### On User Login
|
|
610
|
+
|
|
611
|
+
```javascript
|
|
612
|
+
function handleLogin(user) {
|
|
613
|
+
identify(user.id, { email: user.email, name: user.name });
|
|
614
|
+
setUserProperties({ plan: user.plan });
|
|
615
|
+
setGlobalProperties({ user_id: user.id, role: user.role });
|
|
616
|
+
trackEvent('login', { method: 'email' });
|
|
617
|
+
}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### On User Logout
|
|
621
|
+
|
|
622
|
+
```javascript
|
|
623
|
+
function handleLogout() {
|
|
624
|
+
trackEvent('logout');
|
|
625
|
+
clearGlobalProperties();
|
|
626
|
+
reset();
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Error Handling
|
|
631
|
+
|
|
632
|
+
```javascript
|
|
633
|
+
async function saveProfile(data) {
|
|
634
|
+
try {
|
|
635
|
+
await api.saveProfile(data);
|
|
636
|
+
trackEvent('profile_saved');
|
|
637
|
+
} catch (error) {
|
|
638
|
+
trackError(error, { screen: 'Profile', action: 'save_profile' });
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
---
|
|
644
|
+
|
|
645
|
+
## Migration Guide
|
|
646
|
+
|
|
647
|
+
If you have existing provider-specific code, replace it with unified methods:
|
|
648
|
+
|
|
649
|
+
```javascript
|
|
650
|
+
// Before (provider-specific)
|
|
651
|
+
countly.setUserContext({ user_id: '123' });
|
|
652
|
+
posthog.register({ user_id: '123' });
|
|
653
|
+
|
|
654
|
+
// After (unified)
|
|
655
|
+
setGlobalProperties({ user_id: '123' });
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
## License
|
|
661
|
+
|
|
662
|
+
Internal use only - ANTZ Systems.
|