diff --git a/services/web/app/views/project/_mixpanel_autocapture.pug b/services/web/app/views/project/_mixpanel_autocapture.pug index 184483ff60..b4681292a3 100644 --- a/services/web/app/views/project/_mixpanel_autocapture.pug +++ b/services/web/app/views/project/_mixpanel_autocapture.pug @@ -5,73 +5,74 @@ if user && user.labsProgram && ExposedSettings.mixpanelLabsToken id='mp-loader' data-mixpanel-token=ExposedSettings.mixpanelLabsToken ). - ;(function (f, b) { - if (!b.__SV) { - var e, g, i, h - window.mixpanel = b - b._i = [] - b.init = function (e, f, c) { - function g(a, d) { - var b = d.split('.') - 2 == b.length && ((a = a[b[0]]), (d = b[1])) - a[d] = function () { - a.push([d].concat(Array.prototype.slice.call(arguments, 0))) - } - } - - var a = b - 'undefined' !== typeof c ? (a = b[c] = []) : (c = 'mixpanel') - a.people = a.people || [] - a.toString = function (a) { - var d = 'mixpanel' - 'mixpanel' !== c && (d += '.' + c) - a || (d += ' (stub)') - return d - } - a.people.toString = function () { - return a.toString(1) + '.people (stub)' - } - i = 'disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking start_batch_senders people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove'.split(' ') - for (h = 0; h < i.length; h++) g(a, i[h]) - var j = 'set set_once union unset remove delete'.split(' ') - a.get_group = function () { - function b(c) { - d[c] = function () { - call2_args = arguments - call2 = [c].concat(Array.prototype.slice.call(call2_args, 0)) - a.push([e, call2]) + window.olLoadMixpanelAutocapture = function () { + ;(function (f, b) { + if (!b.__SV) { + var e, g, i, h + window.mixpanel = b + b._i = [] + b.init = function (e, f, c) { + function g(a, d) { + var b = d.split('.') + 2 == b.length && ((a = a[b[0]]), (d = b[1])) + a[d] = function () { + a.push([d].concat(Array.prototype.slice.call(arguments, 0))) } } - for (var d = {}, e = ['get_group'].concat(Array.prototype.slice.call(arguments, 0)), c = 0; c < j.length; c++) b(j[c]) - return d - } - b._i.push([e, f, c]) - } - b.__SV = 1.2 - e = f.createElement('script') - e.type = 'text/javascript' - e.async = !0 - e.src = 'undefined' !== typeof MIXPANEL_CUSTOM_LIB_URL ? MIXPANEL_CUSTOM_LIB_URL : 'file:' === f.location.protocol && '//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js'.match(/^\/\//) ? 'https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js' : '//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js' - g = f.getElementsByTagName('script')[0] - g.parentNode.insertBefore(e, g) - } - })(document, window.mixpanel || []) + var a = b + 'undefined' !== typeof c ? (a = b[c] = []) : (c = 'mixpanel') + a.people = a.people || [] + a.toString = function (a) { + var d = 'mixpanel' + 'mixpanel' !== c && (d += '.' + c) + a || (d += ' (stub)') + return d + } + a.people.toString = function () { + return a.toString(1) + '.people (stub)' + } + i = 'disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking start_batch_senders people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove'.split(' ') + for (h = 0; h < i.length; h++) g(a, i[h]) + var j = 'set set_once union unset remove delete'.split(' ') + a.get_group = function () { + function b(c) { + d[c] = function () { + call2_args = arguments + call2 = [c].concat(Array.prototype.slice.call(call2_args, 0)) + a.push([e, call2]) + } + } - var mixpanelSettings = document.querySelector('#mp-loader').dataset - var mixpanelToken = mixpanelSettings.mixpanelToken - if (mixpanelToken) { - mixpanel.init(mixpanelToken, { - api_host: 'https://api-eu.mixpanel.com', - autocapture: { - capture_text_content: false, - input: true, - rage_click: true, - dead_click: true, - scroll: true, - submit: true, - click: true, - pageview: 'full-url', - }, - }) + for (var d = {}, e = ['get_group'].concat(Array.prototype.slice.call(arguments, 0)), c = 0; c < j.length; c++) b(j[c]) + return d + } + b._i.push([e, f, c]) + } + b.__SV = 1.2 + e = f.createElement('script') + e.type = 'text/javascript' + e.async = !0 + e.src = 'undefined' !== typeof MIXPANEL_CUSTOM_LIB_URL ? MIXPANEL_CUSTOM_LIB_URL : 'file:' === f.location.protocol && '//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js'.match(/^\/\//) ? 'https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js' : '//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js' + g = f.getElementsByTagName('script')[0] + g.parentNode.insertBefore(e, g) + } + })(document, window.mixpanel || []) + var mixpanelSettings = document.querySelector('#mp-loader').dataset + var mixpanelToken = mixpanelSettings.mixpanelToken + if (mixpanelToken) { + mixpanel.init(mixpanelToken, { + api_host: 'https://api-eu.mixpanel.com', + autocapture: { + capture_text_content: false, + input: true, + rage_click: true, + dead_click: true, + scroll: true, + submit: true, + click: true, + pageview: 'full-url', + }, + }) + } } diff --git a/services/web/frontend/js/features/cookie-banner/utils.ts b/services/web/frontend/js/features/cookie-banner/utils.ts index 8438eba55b..ac8dcb8641 100644 --- a/services/web/frontend/js/features/cookie-banner/utils.ts +++ b/services/web/frontend/js/features/cookie-banner/utils.ts @@ -34,7 +34,8 @@ export function cookieBannerRequired() { exposedSettings.gaToken || exposedSettings.gaTokenV4 || exposedSettings.propensityId || - exposedSettings.hotjarId + exposedSettings.hotjarId || + (exposedSettings.mixpanelLabsToken && exposedSettings.labsEnabled) ) } diff --git a/services/web/frontend/js/infrastructure/mixpanel-autocapture.ts b/services/web/frontend/js/infrastructure/mixpanel-autocapture.ts new file mode 100644 index 0000000000..8c1aa14c26 --- /dev/null +++ b/services/web/frontend/js/infrastructure/mixpanel-autocapture.ts @@ -0,0 +1,12 @@ +import { createTrackingLoader } from '@/infrastructure/tracking-loader' + +function initializeMixpanelAutocapture() { + if (window.olLoadMixpanelAutocapture) { + window.olLoadMixpanelAutocapture() + } +} + +createTrackingLoader( + () => initializeMixpanelAutocapture(), + 'MixpanelAutocapture' +) diff --git a/services/web/frontend/js/pages/ide.tsx b/services/web/frontend/js/pages/ide.tsx index 467a4625b8..4261f46a69 100644 --- a/services/web/frontend/js/pages/ide.tsx +++ b/services/web/frontend/js/pages/ide.tsx @@ -1,6 +1,7 @@ import '../utils/webpack-public-path' // configure dynamically loaded assets (via webpack) to be downloaded from CDN import '../infrastructure/error-reporter' // set up error reporting, including Sentry import '../infrastructure/hotjar' // set up Hotjar +import '../infrastructure/mixpanel-autocapture' // set up mixpanel autocapture import { createRoot } from 'react-dom/client' import IdeRoot from '@/features/ide-react/components/ide-root' diff --git a/services/web/frontend/js/pages/project-list.tsx b/services/web/frontend/js/pages/project-list.tsx index b5e2e2fd46..19f5a80cd7 100644 --- a/services/web/frontend/js/pages/project-list.tsx +++ b/services/web/frontend/js/pages/project-list.tsx @@ -1,6 +1,7 @@ import './../utils/meta' import '../utils/webpack-public-path' import './../infrastructure/error-reporter' +import './../infrastructure/mixpanel-autocapture' import '@/i18n' import '../features/event-tracking' import '../features/cookie-banner' diff --git a/services/web/types/exposed-settings.ts b/services/web/types/exposed-settings.ts index 49fbba7c18..e8f939bfc9 100644 --- a/services/web/types/exposed-settings.ts +++ b/services/web/types/exposed-settings.ts @@ -24,6 +24,7 @@ export type ExposedSettings = { ieeeBrandId: number isOverleaf: boolean maxEntitiesPerProject: number + mixpanelLabsToken?: string projectUploadTimeout: number propensityId?: string maxUploadSize: number diff --git a/services/web/types/window.ts b/services/web/types/window.ts index 3ee0453389..3263cde24a 100644 --- a/services/web/types/window.ts +++ b/services/web/types/window.ts @@ -28,6 +28,7 @@ declare global { propensity?: (propensityId?: string) => void olLoadGA?: () => void + olLoadMixpanelAutocapture?: () => void grecaptcha?: ReCaptchaInstance _linkedin_data_partner_ids?: string[] lintrk?: ((a: string, b?: unknown) => void) & {