From f32896d5fa1a8c97703b0d7e0ff97d5a58e8a4cf Mon Sep 17 00:00:00 2001 From: MarconLP <13001502+MarconLP@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:09:01 +0100 Subject: [PATCH] rebase --- playground/nextjs/src/posthog.ts | 2 ++ src/posthog-core.ts | 4 +++- src/site-apps.ts | 39 ++++++++++++++++++++------------ src/types.ts | 3 ++- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/playground/nextjs/src/posthog.ts b/playground/nextjs/src/posthog.ts index 6a4062a34..342904b9a 100644 --- a/playground/nextjs/src/posthog.ts +++ b/playground/nextjs/src/posthog.ts @@ -28,6 +28,7 @@ export const configForConsent = (): Partial => { return { persistence: consentGiven ? 'localStorage+cookie' : 'memory', disable_surveys: !consentGiven, + disable_site_apps_destinations: !consentGiven, autocapture: consentGiven, disable_session_recording: !consentGiven, } @@ -49,6 +50,7 @@ if (typeof window !== 'undefined') { session_recording: { recordCrossOriginIframes: true, }, + opt_in_site_apps: true, debug: true, disable_web_experiments: false, scroll_root_selector: ['#scroll_element', 'html'], diff --git a/src/posthog-core.ts b/src/posthog-core.ts index 49e21a25f..1e2617f63 100644 --- a/src/posthog-core.ts +++ b/src/posthog-core.ts @@ -145,6 +145,7 @@ export const defaultConfig = (): PostHogConfig => ({ disable_persistence: false, disable_web_experiments: true, // disabled in beta. disable_surveys: false, + disable_site_apps_destinations: false, enable_recording_console_log: undefined, // When undefined, it falls back to the server-side setting secure_cookie: window?.location?.protocol === 'https:', ip: true, @@ -308,6 +309,7 @@ export class PostHog { this.scrollManager = new ScrollManager(this) this.pageViewManager = new PageViewManager(this) this.surveys = new PostHogSurveys(this) + this.siteApps = new SiteApps(this) this.experiments = new WebExperiments(this) this.exceptions = new PostHogExceptions(this) this.rateLimiter = new RateLimiter(this) @@ -434,7 +436,6 @@ export class PostHog { new TracingHeaders(this).startIfEnabledOrStop() - this.siteApps = new SiteApps(this) this.siteApps?.init() this.sessionRecording = new SessionRecording(this) @@ -1828,6 +1829,7 @@ export class PostHog { this.autocapture?.startIfEnabled() this.heatmaps?.startIfEnabled() this.surveys.loadIfEnabled() + this.siteApps?.loadIfEnabled() this._sync_opt_out_with_persistence() } } diff --git a/src/site-apps.ts b/src/site-apps.ts index 73414ace1..394cccf65 100644 --- a/src/site-apps.ts +++ b/src/site-apps.ts @@ -5,16 +5,12 @@ import { logger } from './utils/logger' import { isArray } from './utils/type-utils' export class SiteApps { - instance: PostHog - enabled: boolean + private _decideServerResponse?: DecideResponse['siteApps'] missedInvocations: Record[] loaded: boolean appsLoading: Set - constructor(instance: PostHog) { - this.instance = instance - // can't use if site apps are disabled, or if we're not asking /decide for site apps - this.enabled = !!this.instance.config.opt_in_site_apps && !this.instance.config.advanced_disable_decide + constructor(private readonly instance: PostHog) { // events captured between loading posthog-js and the site app; up to 1000 events this.missedInvocations = [] // capture events until loaded @@ -23,7 +19,9 @@ export class SiteApps { } eventCollector(_eventName: string, eventPayload?: CaptureResult | undefined) { - if (!this.enabled) { + // can't use if site apps are disabled, or if we're not asking /decide for site apps + const enabled = this.instance.config.opt_in_site_apps && !this.instance.config.advanced_disable_decide + if (!enabled) { return } if (!this.loaded && eventPayload) { @@ -74,9 +72,15 @@ export class SiteApps { return globals } - afterDecideResponse(response?: DecideResponse): void { - if (isArray(response?.siteApps) && response.siteApps.length > 0) { - if (this.enabled && this.instance.config.opt_in_site_apps) { + loadIfEnabled() { + if ( + this._decideServerResponse && + isArray(this._decideServerResponse) && + this._decideServerResponse.length > 0 + ) { + // can't use if site apps are disabled, or if we're not asking /decide for site apps + const enabled = this.instance.config.opt_in_site_apps && !this.instance.config.advanced_disable_decide + if (enabled) { const checkIfAllLoaded = () => { // Stop collecting events once all site apps are loaded if (this.appsLoading.size === 0) { @@ -84,8 +88,11 @@ export class SiteApps { this.missedInvocations = [] } } - for (const { id, url } of response['siteApps']) { - // TODO: if we have opted out and "type" is "site_destination", ignore it... but do include "site_app" types + for (const { id, type, url } of this._decideServerResponse) { + if (this.instance.config.disable_site_apps_destinations && type === 'site_destination') continue + // if the site app is already loaded, skip it + // eslint-disable-next-line no-restricted-globals + if (`__$$ph_site_app_${id}_posthog` in window) continue this.appsLoading.add(id) assignableWindow[`__$$ph_site_app_${id}_posthog`] = this.instance assignableWindow[`__$$ph_site_app_${id}_missed_invocations`] = () => this.missedInvocations @@ -101,7 +108,7 @@ export class SiteApps { } }) } - } else if (response['siteApps'].length > 0) { + } else if (this._decideServerResponse.length > 0) { logger.error('PostHog site apps are disabled. Enable the "opt_in_site_apps" config to proceed.') this.loaded = true } else { @@ -109,9 +116,11 @@ export class SiteApps { } } else { this.loaded = true - this.enabled = false } } - // TODO: opting out of stuff should disable this + afterDecideResponse(response: DecideResponse): void { + this._decideServerResponse = response['siteApps'] + this.loadIfEnabled() + } } diff --git a/src/types.ts b/src/types.ts index 3044e10df..24a379791 100644 --- a/src/types.ts +++ b/src/types.ts @@ -248,6 +248,7 @@ export interface PostHogConfig { /** @deprecated - use `disable_persistence` instead */ disable_cookie?: boolean disable_surveys: boolean + disable_site_apps_destinations: boolean disable_web_experiments: boolean /** If set, posthog-js will never load external scripts such as those needed for Session Replay or Surveys. */ disable_external_dependency_loading?: boolean @@ -523,7 +524,7 @@ export interface DecideResponse { editorParams?: ToolbarParams /** @deprecated, renamed to toolbarParams, still present on older API responses */ toolbarVersion: 'toolbar' /** @deprecated, moved to toolbarParams */ isAuthenticated: boolean - siteApps: { id: string; url: string }[] + siteApps: { id: string; type: string; url: string }[] heatmaps?: boolean defaultIdentifiedOnly?: boolean captureDeadClicks?: boolean