@deriv-com/analytics 1.32.6 → 1.34.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.
@@ -1,5 +1,6 @@
1
1
  import { Growthbook, GrowthbookConfigs } from './growthbook';
2
2
  import { RudderStack } from './rudderstack';
3
+ import { PostHogAnalytics, PostHogConfig } from './posthog';
3
4
  import { TCoreAttributes, TGrowthbookOptions, TAllEvents } from './types';
4
5
  declare global {
5
6
  interface Window {
@@ -10,11 +11,14 @@ type Options = {
10
11
  growthbookKey?: string;
11
12
  growthbookDecryptionKey?: string;
12
13
  rudderstackKey: string;
14
+ posthogKey?: string;
15
+ posthogHost?: string;
16
+ posthogConfig?: PostHogConfig;
13
17
  growthbookOptions?: TGrowthbookOptions;
14
18
  disableRudderstackAMD?: boolean;
15
19
  };
16
20
  export declare function createAnalyticsInstance(options?: Options): {
17
- initialise: ({ growthbookKey, growthbookDecryptionKey, rudderstackKey, growthbookOptions, disableRudderstackAMD, }: Options) => Promise<void>;
21
+ initialise: ({ growthbookKey, growthbookDecryptionKey, rudderstackKey, posthogKey, posthogHost, posthogConfig, growthbookOptions, disableRudderstackAMD, }: Options) => Promise<void>;
18
22
  setAttributes: ({ country, user_language, device_language, device_type, account_type, user_id, anonymous_id, app_id, utm_source, utm_medium, utm_campaign, is_authorised, residence_country, url, domain, geo_location, loggedIn, network_downlink, network_rtt, network_type, account_currency, account_mode, }: TCoreAttributes) => void;
19
23
  identifyEvent: (user_id?: string) => void;
20
24
  getFeatureState: (id: string) => string | undefined;
@@ -30,12 +34,13 @@ export declare function createAnalyticsInstance(options?: Options): {
30
34
  getInstances: () => {
31
35
  ab: Growthbook;
32
36
  tracking: RudderStack;
37
+ posthog: PostHogAnalytics;
33
38
  };
34
39
  pageView: (current_page: string, platform?: string, properties?: {}) => void;
35
40
  reset: () => void;
36
41
  };
37
42
  export declare const Analytics: {
38
- initialise: ({ growthbookKey, growthbookDecryptionKey, rudderstackKey, growthbookOptions, disableRudderstackAMD, }: Options) => Promise<void>;
43
+ initialise: ({ growthbookKey, growthbookDecryptionKey, rudderstackKey, posthogKey, posthogHost, posthogConfig, growthbookOptions, disableRudderstackAMD, }: Options) => Promise<void>;
39
44
  setAttributes: ({ country, user_language, device_language, device_type, account_type, user_id, anonymous_id, app_id, utm_source, utm_medium, utm_campaign, is_authorised, residence_country, url, domain, geo_location, loggedIn, network_downlink, network_rtt, network_type, account_currency, account_mode, }: TCoreAttributes) => void;
40
45
  identifyEvent: (user_id?: string) => void;
41
46
  getFeatureState: (id: string) => string | undefined;
@@ -51,6 +56,7 @@ export declare const Analytics: {
51
56
  getInstances: () => {
52
57
  ab: Growthbook;
53
58
  tracking: RudderStack;
59
+ posthog: PostHogAnalytics;
54
60
  };
55
61
  pageView: (current_page: string, platform?: string, properties?: {}) => void;
56
62
  reset: () => void;
package/lib/analytics.js CHANGED
@@ -53,11 +53,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
53
53
  exports.Analytics = exports.createAnalyticsInstance = void 0;
54
54
  var growthbook_1 = require("./growthbook");
55
55
  var rudderstack_1 = require("./rudderstack");
56
+ var posthog_1 = require("./posthog");
56
57
  var js_cookie_1 = __importDefault(require("js-cookie"));
57
58
  var utils_1 = require("@deriv-com/utils");
58
59
  function createAnalyticsInstance(options) {
59
60
  var _this = this;
60
- var _growthbook, _rudderstack, core_data = {}, tracking_config = {}, event_cache = [], _pending_identify_calls = [];
61
+ var _growthbook, _rudderstack, _posthog, core_data = {}, tracking_config = {}, event_cache = [], _pending_identify_calls = [];
61
62
  var getClientCountry = function () { return __awaiter(_this, void 0, void 0, function () {
62
63
  var countryFromCloudflare, countryFromCookie, websiteStatus, countryFromWebsiteStatus;
63
64
  var _a;
@@ -82,7 +83,7 @@ function createAnalyticsInstance(options) {
82
83
  });
83
84
  }); };
84
85
  var initialise = function (_a) {
85
- var growthbookKey = _a.growthbookKey, growthbookDecryptionKey = _a.growthbookDecryptionKey, rudderstackKey = _a.rudderstackKey, growthbookOptions = _a.growthbookOptions, _b = _a.disableRudderstackAMD, disableRudderstackAMD = _b === void 0 ? false : _b;
86
+ var growthbookKey = _a.growthbookKey, growthbookDecryptionKey = _a.growthbookDecryptionKey, rudderstackKey = _a.rudderstackKey, posthogKey = _a.posthogKey, posthogHost = _a.posthogHost, posthogConfig = _a.posthogConfig, growthbookOptions = _a.growthbookOptions, _b = _a.disableRudderstackAMD, disableRudderstackAMD = _b === void 0 ? false : _b;
86
87
  return __awaiter(_this, void 0, void 0, function () {
87
88
  var country, _c, interval_1, error_1;
88
89
  var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
@@ -99,16 +100,35 @@ function createAnalyticsInstance(options) {
99
100
  _2.label = 2;
100
101
  case 2:
101
102
  country = _c;
103
+ // Initialize RudderStack
102
104
  _rudderstack = rudderstack_1.RudderStack.getRudderStackInstance(rudderstackKey, disableRudderstackAMD, function () {
103
105
  _pending_identify_calls.forEach(function (userId) {
104
106
  if (userId) {
105
107
  _rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.identifyEvent(userId, {
106
108
  language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
107
109
  });
110
+ // Also identify in PostHog if initialized
111
+ if (_posthog === null || _posthog === void 0 ? void 0 : _posthog.has_initialized) {
112
+ _posthog === null || _posthog === void 0 ? void 0 : _posthog.identifyEvent(userId, {
113
+ language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
114
+ });
115
+ }
108
116
  }
109
117
  });
110
118
  _pending_identify_calls = [];
111
119
  });
120
+ // Initialize PostHog only if key is provided
121
+ if (posthogKey) {
122
+ _posthog = posthog_1.PostHogAnalytics.getPostHogInstance(posthogKey, posthogHost || 'https://ph.deriv.com', disableRudderstackAMD, function () {
123
+ _pending_identify_calls.forEach(function (userId) {
124
+ if (userId) {
125
+ _posthog === null || _posthog === void 0 ? void 0 : _posthog.identifyEvent(userId, {
126
+ language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
127
+ });
128
+ }
129
+ });
130
+ }, posthogConfig);
131
+ }
112
132
  if ((growthbookOptions === null || growthbookOptions === void 0 ? void 0 : growthbookOptions.attributes) && Object.keys(growthbookOptions.attributes).length > 0)
113
133
  core_data = __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({}, core_data), { country: country }), (((_e = growthbookOptions === null || growthbookOptions === void 0 ? void 0 : growthbookOptions.attributes) === null || _e === void 0 ? void 0 : _e.user_language) && {
114
134
  user_language: growthbookOptions === null || growthbookOptions === void 0 ? void 0 : growthbookOptions.attributes.user_language,
@@ -192,23 +212,35 @@ function createAnalyticsInstance(options) {
192
212
  return userId && !isUUID(userId) ? userId : '';
193
213
  };
194
214
  /**
195
- * Pushes page view event to Rudderstack
215
+ * Pushes page view event to RudderStack and PostHog
196
216
  *
197
- * @param curret_page The name or URL of the current page to track the page view event
217
+ * @param current_page The name or URL of the current page to track the page view event
198
218
  */
199
219
  var pageView = function (current_page, platform, properties) {
200
220
  if (platform === void 0) { platform = 'Deriv App'; }
201
221
  if (!_rudderstack)
202
222
  return;
203
223
  var userId = getId();
224
+ // Send to RudderStack
204
225
  _rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.pageView(current_page, platform, userId, properties);
226
+ // Send to PostHog (if initialized)
227
+ _posthog === null || _posthog === void 0 ? void 0 : _posthog.pageView(current_page, platform, userId, properties);
205
228
  };
206
229
  var identifyEvent = function (user_id) {
207
230
  var stored_user_id = user_id || getId();
208
- if ((_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.has_initialized) && stored_user_id) {
209
- _rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.identifyEvent(stored_user_id, {
210
- language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
211
- });
231
+ if (((_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.has_initialized) || (_posthog === null || _posthog === void 0 ? void 0 : _posthog.has_initialized)) && stored_user_id) {
232
+ // Identify in RudderStack
233
+ if (_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.has_initialized) {
234
+ _rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.identifyEvent(stored_user_id, {
235
+ language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
236
+ });
237
+ }
238
+ // Identify in PostHog (if initialized)
239
+ if (_posthog === null || _posthog === void 0 ? void 0 : _posthog.has_initialized) {
240
+ _posthog === null || _posthog === void 0 ? void 0 : _posthog.identifyEvent(stored_user_id, {
241
+ language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
242
+ });
243
+ }
212
244
  return;
213
245
  }
214
246
  if (stored_user_id) {
@@ -216,9 +248,12 @@ function createAnalyticsInstance(options) {
216
248
  }
217
249
  };
218
250
  var reset = function () {
219
- if (!_rudderstack)
251
+ if (!_rudderstack && !_posthog)
220
252
  return;
253
+ // Reset RudderStack
221
254
  _rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.reset();
255
+ // Reset PostHog (if initialized)
256
+ _posthog === null || _posthog === void 0 ? void 0 : _posthog.reset();
222
257
  };
223
258
  var isV2Payload = function (payload) {
224
259
  return 'event_metadata' in payload || 'cta_information' in payload || 'error' in payload;
@@ -235,25 +270,33 @@ function createAnalyticsInstance(options) {
235
270
  // --- V1 LOGIC: Flatten Core Data (Backward Compatible) ---
236
271
  final_payload = __assign(__assign(__assign({}, core_data), analytics_data), (userId && { user_id: userId }));
237
272
  }
238
- if (navigator.onLine && _rudderstack) {
273
+ if (navigator.onLine && (_rudderstack || _posthog)) {
239
274
  if (event_cache.length > 0) {
240
275
  event_cache.forEach(function (cache, index) {
241
- _rudderstack.track(cache.event, cache.payload);
276
+ // Send cached events to both providers
277
+ _rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.track(cache.event, cache.payload);
278
+ _posthog === null || _posthog === void 0 ? void 0 : _posthog.track(cache.event, cache.payload);
242
279
  delete event_cache[index];
243
280
  });
244
281
  }
245
282
  if (event in tracking_config) {
246
- tracking_config[event] && (_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.track(event, final_payload));
283
+ if (tracking_config[event]) {
284
+ // Send to both RudderStack and PostHog
285
+ _rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.track(event, final_payload);
286
+ _posthog === null || _posthog === void 0 ? void 0 : _posthog.track(event, final_payload);
287
+ }
247
288
  }
248
289
  else {
290
+ // Send to both RudderStack and PostHog
249
291
  _rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.track(event, final_payload);
292
+ _posthog === null || _posthog === void 0 ? void 0 : _posthog.track(event, final_payload);
250
293
  }
251
294
  }
252
295
  else {
253
296
  event_cache.push({ event: event, payload: final_payload });
254
297
  }
255
298
  };
256
- var getInstances = function () { return ({ ab: _growthbook, tracking: _rudderstack }); };
299
+ var getInstances = function () { return ({ ab: _growthbook, tracking: _rudderstack, posthog: _posthog }); };
257
300
  var AnalyticsInstance = {
258
301
  initialise: initialise,
259
302
  setAttributes: setAttributes,
@@ -0,0 +1,63 @@
1
+ import type { PostHogConfig as PostHogInitConfig } from 'posthog-js';
2
+ import { TCoreAttributes, TAllEvents } from './types';
3
+ export type PostHogConfig = Omit<Partial<PostHogInitConfig>, 'api_host' | 'ui_host' | 'bootstrap' | 'loaded'> & {
4
+ capture_pageview?: boolean;
5
+ capture_pageleave?: boolean;
6
+ autocapture?: boolean;
7
+ };
8
+ export declare class PostHogAnalytics {
9
+ has_identified: boolean;
10
+ has_initialized: boolean;
11
+ current_page: string;
12
+ rudderstack_anonymous_cookie_key: string;
13
+ private static _instance;
14
+ private onLoadedCallback?;
15
+ constructor(POSTHOG_KEY: string, POSTHOG_HOST?: string, disableAMD?: boolean, onLoaded?: () => void, config?: PostHogConfig);
16
+ static getPostHogInstance: (POSTHOG_KEY: string, POSTHOG_HOST?: string, disableAMD?: boolean, onLoaded?: () => void, config?: PostHogConfig) => PostHogAnalytics;
17
+ getAnonymousId: () => string | undefined;
18
+ setCookieIfNotExists: () => void;
19
+ /**
20
+ * @returns The user ID that was assigned to the user after calling identify event
21
+ */
22
+ getUserId: () => string;
23
+ /** For caching mechanism, PostHog SDK, first page load */
24
+ handleCachedEvents: () => void;
25
+ /**
26
+ * Transform V2 event payload to PostHog flat structure
27
+ */
28
+ private transformToPostHogPayload;
29
+ /**
30
+ * Initializes the PostHog SDK using proxy endpoint.
31
+ * For local/staging environment, ensure that `POSTHOG_STAGING_KEY` is set.
32
+ * For production environment, ensure that `POSTHOG_PRODUCTION_KEY` is set.
33
+ *
34
+ * Proxy Setup:
35
+ * - Using https://ph.deriv.com as proxy endpoint (same for staging and production)
36
+ * - Proxy forwards requests to PostHog Cloud
37
+ * - X-headers are configured on the proxy server (not client-side)
38
+ * - See: https://posthog.com/docs/advanced/proxy
39
+ */
40
+ init: (POSTHOG_KEY: string, POSTHOG_HOST?: string, disableAMD?: boolean, config?: PostHogConfig) => void;
41
+ /**
42
+ *
43
+ * @param user_id The user ID of the user to identify and associate all events with that particular user ID
44
+ * @param payload Additional information passed to identify the user
45
+ */
46
+ identifyEvent: (user_id: string, payload: {
47
+ language: string;
48
+ }) => void;
49
+ /**
50
+ * Pushes page view event to PostHog
51
+ *
52
+ * @param current_page The name or URL of the current page to track the page view event
53
+ */
54
+ pageView: (current_page: string, platform: string | undefined, user_id: string, properties?: {}) => void;
55
+ /**
56
+ * Pushes reset event to PostHog
57
+ */
58
+ reset: () => void;
59
+ /**
60
+ * Pushes track events to PostHog with automatic payload transformation
61
+ */
62
+ track: <T extends keyof import("./types").TEvents | "ce_get_start_page">(event: T, payload: TAllEvents[T] & Partial<TCoreAttributes>) => void;
63
+ }
package/lib/posthog.js ADDED
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.PostHogAnalytics = void 0;
18
+ var posthog_js_1 = __importDefault(require("posthog-js"));
19
+ var uuid_1 = require("uuid");
20
+ var js_cookie_1 = __importDefault(require("js-cookie"));
21
+ var PostHogAnalytics = /** @class */ (function () {
22
+ function PostHogAnalytics(POSTHOG_KEY, POSTHOG_HOST, disableAMD, onLoaded, config) {
23
+ if (disableAMD === void 0) { disableAMD = false; }
24
+ var _this = this;
25
+ this.has_identified = false;
26
+ this.has_initialized = false;
27
+ this.current_page = '';
28
+ // Share the same anonymous ID cookie with RudderStack
29
+ this.rudderstack_anonymous_cookie_key = 'rudder_anonymous_id';
30
+ this.getAnonymousId = function () {
31
+ var _a;
32
+ return (_a = document.cookie.match('(^|;)\\s*' + _this.rudderstack_anonymous_cookie_key + '\\s*=\\s*([^;]+)')) === null || _a === void 0 ? void 0 : _a.pop();
33
+ };
34
+ this.setCookieIfNotExists = function () {
35
+ var anonymous_id = _this.getAnonymousId();
36
+ if (!anonymous_id) {
37
+ var hostname_1 = window.location.hostname;
38
+ // List of external domains where we should use the full hostname
39
+ var external_domains = ['webflow.io'];
40
+ // Check if the hostname ends with any of the external domains
41
+ var is_external_domain = external_domains.some(function (domain) { return hostname_1.endsWith(domain); });
42
+ // If it's an external domain, use the full hostname, otherwise use the last two parts
43
+ var domain_name = is_external_domain ? hostname_1 : hostname_1.split('.').slice(-2).join('.');
44
+ // Set cookie to expire in 2 years
45
+ document.cookie = "".concat(_this.rudderstack_anonymous_cookie_key, "=").concat((0, uuid_1.v6)(), "; path=/; Domain=").concat(domain_name, "; max-age=").concat(2 * 365 * 24 * 60 * 60);
46
+ }
47
+ };
48
+ /**
49
+ * @returns The user ID that was assigned to the user after calling identify event
50
+ */
51
+ this.getUserId = function () { return posthog_js_1.default.get_distinct_id(); };
52
+ /** For caching mechanism, PostHog SDK, first page load */
53
+ this.handleCachedEvents = function () {
54
+ var allowedDomains = ['deriv.com', 'deriv.team', 'deriv.ae'];
55
+ var domain = allowedDomains.some(function (d) { return window.location.hostname.includes(d); })
56
+ ? ".".concat(allowedDomains.find(function (d) { return window.location.hostname.includes(d); }))
57
+ : ".".concat(allowedDomains[0]);
58
+ var storedEventsString = js_cookie_1.default.get('cached_analytics_events');
59
+ var storedPagesString = js_cookie_1.default.get('cached_analytics_page_views');
60
+ try {
61
+ // Handle cached analytics events
62
+ if (storedEventsString) {
63
+ var storedEvents = JSON.parse(storedEventsString);
64
+ if (Array.isArray(storedEvents) && storedEvents.length > 0) {
65
+ storedEvents.forEach(function (event) {
66
+ posthog_js_1.default.capture(event.name, event.properties);
67
+ });
68
+ // Clear the stored events cookie
69
+ js_cookie_1.default.remove('cached_analytics_events', { domain: domain });
70
+ }
71
+ }
72
+ // Handle cached page views
73
+ if (storedPagesString) {
74
+ var storedPages = JSON.parse(storedPagesString);
75
+ if (Array.isArray(storedPages) && storedPages.length > 0) {
76
+ storedPages.forEach(function (page) {
77
+ posthog_js_1.default.capture('$pageview', __assign({ $current_url: window.location.href, page_name: page === null || page === void 0 ? void 0 : page.name }, page === null || page === void 0 ? void 0 : page.properties));
78
+ });
79
+ // Clear the stored page views cookie
80
+ js_cookie_1.default.remove('cached_analytics_page_views', { domain: domain });
81
+ }
82
+ }
83
+ }
84
+ catch (error) {
85
+ // eslint-disable-next-line no-console
86
+ console.log(error);
87
+ }
88
+ };
89
+ /**
90
+ * Transform V2 event payload to PostHog flat structure
91
+ */
92
+ this.transformToPostHogPayload = function (payload) {
93
+ var transformed = {};
94
+ // Flatten event_metadata
95
+ if (payload.event_metadata) {
96
+ Object.keys(payload.event_metadata).forEach(function (key) {
97
+ // Handle nested marketing_data within event_metadata
98
+ if (key === 'marketing_data' && typeof payload.event_metadata[key] === 'object') {
99
+ var marketingData_1 = payload.event_metadata[key];
100
+ Object.keys(marketingData_1).forEach(function (marketingKey) {
101
+ // Flatten utm_data within marketing_data
102
+ if (marketingKey === 'utm_data') {
103
+ try {
104
+ // Parse utm_data if it's a JSON string
105
+ var utmData_1 = typeof marketingData_1[marketingKey] === 'string'
106
+ ? JSON.parse(marketingData_1[marketingKey])
107
+ : marketingData_1[marketingKey];
108
+ // Flatten utm_data properties to root level
109
+ if (typeof utmData_1 === 'object' && utmData_1 !== null) {
110
+ Object.keys(utmData_1).forEach(function (utmKey) {
111
+ transformed[utmKey] = utmData_1[utmKey];
112
+ });
113
+ }
114
+ }
115
+ catch (error) {
116
+ // If parsing fails, add the raw value
117
+ console.error('Failed to parse utm_data:', error);
118
+ transformed[marketingKey] = marketingData_1[marketingKey];
119
+ }
120
+ }
121
+ else {
122
+ // Add other marketing_data properties directly
123
+ transformed[marketingKey] = marketingData_1[marketingKey];
124
+ }
125
+ });
126
+ }
127
+ else {
128
+ transformed[key] = payload.event_metadata[key];
129
+ }
130
+ });
131
+ }
132
+ // Flatten cta_information
133
+ if (payload.cta_information) {
134
+ Object.keys(payload.cta_information).forEach(function (key) {
135
+ transformed[key] = payload.cta_information[key];
136
+ });
137
+ }
138
+ // Flatten error
139
+ if (payload.error) {
140
+ Object.keys(payload.error).forEach(function (key) {
141
+ transformed[key] = payload.error[key];
142
+ });
143
+ }
144
+ // Add top-level properties (excluding nested objects)
145
+ Object.keys(payload).forEach(function (key) {
146
+ if (!['event_metadata', 'cta_information', 'error'].includes(key)) {
147
+ transformed[key] = payload[key];
148
+ }
149
+ });
150
+ return transformed;
151
+ };
152
+ /**
153
+ * Initializes the PostHog SDK using proxy endpoint.
154
+ * For local/staging environment, ensure that `POSTHOG_STAGING_KEY` is set.
155
+ * For production environment, ensure that `POSTHOG_PRODUCTION_KEY` is set.
156
+ *
157
+ * Proxy Setup:
158
+ * - Using https://ph.deriv.com as proxy endpoint (same for staging and production)
159
+ * - Proxy forwards requests to PostHog Cloud
160
+ * - X-headers are configured on the proxy server (not client-side)
161
+ * - See: https://posthog.com/docs/advanced/proxy
162
+ */
163
+ this.init = function (POSTHOG_KEY, POSTHOG_HOST, disableAMD, config) {
164
+ if (disableAMD === void 0) { disableAMD = false; }
165
+ if (POSTHOG_KEY) {
166
+ var _define_1;
167
+ if (disableAMD) {
168
+ _define_1 = window.define;
169
+ window.define = undefined;
170
+ }
171
+ _this.setCookieIfNotExists();
172
+ // Get the shared anonymous ID from cookie
173
+ var anonymous_id_1 = _this.getAnonymousId();
174
+ posthog_js_1.default.init(POSTHOG_KEY, __assign(__assign({
175
+ // Use proxy endpoint for both staging and production
176
+ // Default to https://ph.deriv.com, can be overridden via POSTHOG_HOST parameter
177
+ api_host: POSTHOG_HOST || 'https://ph.deriv.com',
178
+ // UI host should point to PostHog Cloud for dashboard links
179
+ ui_host: 'https://us.posthog.com',
180
+ // Use the same anonymous ID as RudderStack
181
+ bootstrap: {
182
+ distinctID: anonymous_id_1,
183
+ },
184
+ // Default configurations
185
+ capture_pageview: false, capture_pageleave: false, autocapture: true }, config), { loaded: function (ph) {
186
+ var _a;
187
+ if (disableAMD) {
188
+ window.define = _define_1;
189
+ }
190
+ _this.has_initialized = true;
191
+ // Check if user is already identified
192
+ _this.has_identified = posthog_js_1.default.get_distinct_id() !== anonymous_id_1;
193
+ _this.handleCachedEvents();
194
+ (_a = _this.onLoadedCallback) === null || _a === void 0 ? void 0 : _a.call(_this);
195
+ } }));
196
+ }
197
+ };
198
+ /**
199
+ *
200
+ * @param user_id The user ID of the user to identify and associate all events with that particular user ID
201
+ * @param payload Additional information passed to identify the user
202
+ */
203
+ this.identifyEvent = function (user_id, payload) {
204
+ var currentUserId = _this.getUserId();
205
+ var anonymousId = _this.getAnonymousId();
206
+ // Only identify if not already identified or if it's still using anonymous ID
207
+ if (!currentUserId || currentUserId === anonymousId) {
208
+ // CRITICAL: Use alias to link anonymous ID with user ID before identifying
209
+ // This preserves the pre-signup journey in PostHog
210
+ if (anonymousId && currentUserId === anonymousId) {
211
+ posthog_js_1.default.alias(user_id, anonymousId);
212
+ }
213
+ posthog_js_1.default.identify(user_id, payload);
214
+ }
215
+ _this.has_identified = true;
216
+ };
217
+ /**
218
+ * Pushes page view event to PostHog
219
+ *
220
+ * @param current_page The name or URL of the current page to track the page view event
221
+ */
222
+ this.pageView = function (current_page, platform, user_id, properties) {
223
+ if (platform === void 0) { platform = 'Deriv App'; }
224
+ if (_this.has_initialized && current_page !== _this.current_page) {
225
+ var pageProperties = user_id ? __assign({ user_id: user_id, platform: platform }, properties) : __assign({ platform: platform }, properties);
226
+ posthog_js_1.default.capture('$pageview', __assign({ $current_url: window.location.href, page_name: current_page }, pageProperties));
227
+ _this.current_page = current_page;
228
+ }
229
+ };
230
+ /**
231
+ * Pushes reset event to PostHog
232
+ */
233
+ this.reset = function () {
234
+ if (_this.has_initialized) {
235
+ posthog_js_1.default.reset();
236
+ _this.has_identified = false;
237
+ }
238
+ };
239
+ /**
240
+ * Pushes track events to PostHog with automatic payload transformation
241
+ */
242
+ this.track = function (event, payload) {
243
+ if (_this.has_initialized) {
244
+ try {
245
+ // Transform payload to flat structure for PostHog
246
+ var transformedPayload = _this.transformToPostHogPayload(payload);
247
+ // Clean undefined values
248
+ var clean_payload = Object.fromEntries(Object.entries(transformedPayload).filter(function (_a) {
249
+ var _ = _a[0], value = _a[1];
250
+ return value !== undefined;
251
+ }));
252
+ posthog_js_1.default.capture(event, clean_payload);
253
+ }
254
+ catch (err) {
255
+ console.error(err);
256
+ }
257
+ }
258
+ };
259
+ this.onLoadedCallback = onLoaded;
260
+ this.init(POSTHOG_KEY, POSTHOG_HOST, disableAMD, config);
261
+ }
262
+ PostHogAnalytics.getPostHogInstance = function (POSTHOG_KEY, POSTHOG_HOST, disableAMD, onLoaded, config) {
263
+ if (disableAMD === void 0) { disableAMD = false; }
264
+ if (!PostHogAnalytics._instance) {
265
+ PostHogAnalytics._instance = new PostHogAnalytics(POSTHOG_KEY, POSTHOG_HOST, disableAMD, onLoaded, config);
266
+ return PostHogAnalytics._instance;
267
+ }
268
+ return PostHogAnalytics._instance;
269
+ };
270
+ return PostHogAnalytics;
271
+ }());
272
+ exports.PostHogAnalytics = PostHogAnalytics;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deriv-com/analytics",
3
- "version": "1.32.6",
3
+ "version": "1.34.0",
4
4
  "description": "The analytics package contains all the utility functions used for tracking user events and sending them to the respective platform such as Rudderstack.",
5
5
  "keywords": [
6
6
  "rudderstack",
@@ -56,6 +56,7 @@
56
56
  "@growthbook/growthbook": "^1.1.0",
57
57
  "@rudderstack/analytics-js": "^3.5.1",
58
58
  "js-cookie": "^3.0.5",
59
+ "posthog-js": "^1.313.0",
59
60
  "uuid": "^10.0.0"
60
61
  },
61
62
  "engines": {