posthog-js 1.158.2 → 1.159.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/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "posthog-js",
3
- "version": "1.158.2",
3
+ "version": "1.159.0",
4
4
  "description": "Posthog-js allows you to automatically capture usage and send events to PostHog.",
5
5
  "repository": "https://github.com/PostHog/posthog-js",
6
6
  "author": "hey@posthog.com",
@@ -2,7 +2,7 @@ import { PostHog } from '../../posthog-core';
2
2
  import { DecideResponse, Properties } from '../../types';
3
3
  export declare const BASE_ERROR_ENDPOINT = "/e/";
4
4
  export declare class ExceptionObserver {
5
- private _endpoint;
5
+ private _endpointSuffix;
6
6
  instance: PostHog;
7
7
  remoteEnabled: boolean | undefined;
8
8
  private originalOnUnhandledRejectionHandler;
@@ -34,12 +34,13 @@ var ExceptionObserver = /** @class */ (function () {
34
34
  this.instance = instance;
35
35
  this.remoteEnabled = !!((_a = this.instance.persistence) === null || _a === void 0 ? void 0 : _a.props[EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]);
36
36
  // TODO: once BASE_ERROR_ENDPOINT is no longer /e/ this can be removed
37
- this._endpoint = ((_b = this.instance.persistence) === null || _b === void 0 ? void 0 : _b.props[EXCEPTION_CAPTURE_ENDPOINT]) || BASE_ERROR_ENDPOINT;
37
+ this._endpointSuffix = ((_b = this.instance.persistence) === null || _b === void 0 ? void 0 : _b.props[EXCEPTION_CAPTURE_ENDPOINT]) || BASE_ERROR_ENDPOINT;
38
38
  this.startIfEnabled();
39
39
  }
40
40
  Object.defineProperty(ExceptionObserver.prototype, "endpoint", {
41
41
  get: function () {
42
- return this._endpoint;
42
+ // Always respect any api_host set by the client config
43
+ return this.instance.requestRouter.endpointFor('api', this._endpointSuffix);
43
44
  },
44
45
  enumerable: false,
45
46
  configurable: true
@@ -95,7 +96,7 @@ var ExceptionObserver = /** @class */ (function () {
95
96
  var autocaptureExceptionsResponse = response.autocaptureExceptions;
96
97
  // store this in-memory in case persistence is disabled
97
98
  this.remoteEnabled = !!autocaptureExceptionsResponse || false;
98
- this._endpoint = isObject(autocaptureExceptionsResponse)
99
+ this._endpointSuffix = isObject(autocaptureExceptionsResponse)
99
100
  ? autocaptureExceptionsResponse.endpoint || BASE_ERROR_ENDPOINT
100
101
  : BASE_ERROR_ENDPOINT;
101
102
  if (this.instance.persistence) {
@@ -106,7 +107,7 @@ var ExceptionObserver = /** @class */ (function () {
106
107
  // we'll want that to persist between startup and decide response
107
108
  // TODO: once BASE_ENDPOINT is no longer /e/ this can be removed
108
109
  this.instance.persistence.register((_b = {},
109
- _b[EXCEPTION_CAPTURE_ENDPOINT] = this._endpoint,
110
+ _b[EXCEPTION_CAPTURE_ENDPOINT] = this._endpointSuffix,
110
111
  _b));
111
112
  }
112
113
  this.startIfEnabled();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/extensions/exception-autocapture/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { window } from '../../utils/globals'\nimport { PostHog } from '../../posthog-core'\nimport { DecideResponse, Properties } from '../../types'\n\nimport { isObject } from '../../utils/type-utils'\nimport { logger } from '../../utils/logger'\nimport { EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE, EXCEPTION_CAPTURE_ENDPOINT } from '../../constants'\nimport Config from '../../config'\n\n// TODO: move this to /x/ as default\nexport const BASE_ERROR_ENDPOINT = '/e/'\nconst LOGGER_PREFIX = '[Exception Capture]'\n\nexport class ExceptionObserver {\n private _endpoint: string\n instance: PostHog\n remoteEnabled: boolean | undefined\n private originalOnUnhandledRejectionHandler: Window['onunhandledrejection'] | null | undefined = undefined\n private unwrapOnError: (() => void) | undefined\n private unwrapUnhandledRejection: (() => void) | undefined\n\n constructor(instance: PostHog) {\n this.instance = instance\n this.remoteEnabled = !!this.instance.persistence?.props[EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]\n\n // TODO: once BASE_ERROR_ENDPOINT is no longer /e/ this can be removed\n this._endpoint = this.instance.persistence?.props[EXCEPTION_CAPTURE_ENDPOINT] || BASE_ERROR_ENDPOINT\n\n this.startIfEnabled()\n }\n\n get endpoint() {\n return this._endpoint\n }\n\n get isEnabled() {\n return this.remoteEnabled ?? false\n }\n\n get isCapturing() {\n return !!(window?.onerror as any)?.__POSTHOG_INSTRUMENTED__\n }\n\n get hasHandlers() {\n return this.originalOnUnhandledRejectionHandler || this.unwrapOnError\n }\n\n startIfEnabled(): void {\n if (this.isEnabled && !this.isCapturing) {\n logger.info(LOGGER_PREFIX + ' enabled, starting...')\n this.loadScript(this.startCapturing)\n }\n }\n\n private loadScript(cb: () => void): void {\n if (this.hasHandlers) {\n // already loaded\n cb()\n }\n\n this.instance.requestRouter.loadScript(`/static/exception-autocapture.js?v=${Config.LIB_VERSION}`, (err) => {\n if (err) {\n return logger.error(LOGGER_PREFIX + ' failed to load script', err)\n }\n cb()\n })\n }\n\n private startCapturing = () => {\n if (!window || !this.isEnabled || this.hasHandlers || (window.onerror as any)?.__POSTHOG_INSTRUMENTED__) {\n return\n }\n\n const wrapOnError = (window as any).posthogErrorWrappingFunctions.wrapOnError\n const wrapUnhandledRejection = (window as any).posthogErrorWrappingFunctions.wrapUnhandledRejection\n\n if (!wrapOnError || !wrapUnhandledRejection) {\n logger.error(LOGGER_PREFIX + ' failed to load error wrapping functions - cannot start')\n return\n }\n\n try {\n this.unwrapOnError = wrapOnError(this.captureException.bind(this))\n this.unwrapUnhandledRejection = wrapUnhandledRejection(this.captureException.bind(this))\n } catch (e) {\n logger.error(LOGGER_PREFIX + ' failed to start', e)\n this.stopCapturing()\n }\n }\n\n private stopCapturing() {\n this.unwrapOnError?.()\n this.unwrapUnhandledRejection?.()\n }\n\n afterDecideResponse(response: DecideResponse) {\n const autocaptureExceptionsResponse = response.autocaptureExceptions\n\n // store this in-memory in case persistence is disabled\n this.remoteEnabled = !!autocaptureExceptionsResponse || false\n this._endpoint = isObject(autocaptureExceptionsResponse)\n ? autocaptureExceptionsResponse.endpoint || BASE_ERROR_ENDPOINT\n : BASE_ERROR_ENDPOINT\n\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]: this.remoteEnabled,\n })\n // when we come to moving the endpoint to not /e/\n // we'll want that to persist between startup and decide response\n // TODO: once BASE_ENDPOINT is no longer /e/ this can be removed\n this.instance.persistence.register({\n [EXCEPTION_CAPTURE_ENDPOINT]: this._endpoint,\n })\n }\n\n this.startIfEnabled()\n }\n\n captureException(errorProperties: Properties) {\n const posthogHost = this.instance.requestRouter.endpointFor('ui')\n\n errorProperties.$exception_personURL = `${posthogHost}/project/${\n this.instance.config.token\n }/person/${this.instance.get_distinct_id()}`\n\n this.sendExceptionEvent(errorProperties)\n }\n\n /**\n * :TRICKY: Make sure we batch these requests\n */\n sendExceptionEvent(properties: { [key: string]: any }) {\n this.instance.capture('$exception', properties, {\n _noTruncate: true,\n _batchKey: 'exceptionEvent',\n _url: this.endpoint,\n })\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/extensions/exception-autocapture/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { window } from '../../utils/globals'\nimport { PostHog } from '../../posthog-core'\nimport { DecideResponse, Properties } from '../../types'\n\nimport { isObject } from '../../utils/type-utils'\nimport { logger } from '../../utils/logger'\nimport { EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE, EXCEPTION_CAPTURE_ENDPOINT } from '../../constants'\nimport Config from '../../config'\n\n// TODO: move this to /x/ as default\nexport const BASE_ERROR_ENDPOINT = '/e/'\nconst LOGGER_PREFIX = '[Exception Capture]'\n\nexport class ExceptionObserver {\n private _endpointSuffix: string\n instance: PostHog\n remoteEnabled: boolean | undefined\n private originalOnUnhandledRejectionHandler: Window['onunhandledrejection'] | null | undefined = undefined\n private unwrapOnError: (() => void) | undefined\n private unwrapUnhandledRejection: (() => void) | undefined\n\n constructor(instance: PostHog) {\n this.instance = instance\n this.remoteEnabled = !!this.instance.persistence?.props[EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]\n\n // TODO: once BASE_ERROR_ENDPOINT is no longer /e/ this can be removed\n this._endpointSuffix = this.instance.persistence?.props[EXCEPTION_CAPTURE_ENDPOINT] || BASE_ERROR_ENDPOINT\n\n this.startIfEnabled()\n }\n\n get endpoint() {\n // Always respect any api_host set by the client config\n return this.instance.requestRouter.endpointFor('api', this._endpointSuffix)\n }\n\n get isEnabled() {\n return this.remoteEnabled ?? false\n }\n\n get isCapturing() {\n return !!(window?.onerror as any)?.__POSTHOG_INSTRUMENTED__\n }\n\n get hasHandlers() {\n return this.originalOnUnhandledRejectionHandler || this.unwrapOnError\n }\n\n startIfEnabled(): void {\n if (this.isEnabled && !this.isCapturing) {\n logger.info(LOGGER_PREFIX + ' enabled, starting...')\n this.loadScript(this.startCapturing)\n }\n }\n\n private loadScript(cb: () => void): void {\n if (this.hasHandlers) {\n // already loaded\n cb()\n }\n\n this.instance.requestRouter.loadScript(`/static/exception-autocapture.js?v=${Config.LIB_VERSION}`, (err) => {\n if (err) {\n return logger.error(LOGGER_PREFIX + ' failed to load script', err)\n }\n cb()\n })\n }\n\n private startCapturing = () => {\n if (!window || !this.isEnabled || this.hasHandlers || (window.onerror as any)?.__POSTHOG_INSTRUMENTED__) {\n return\n }\n\n const wrapOnError = (window as any).posthogErrorWrappingFunctions.wrapOnError\n const wrapUnhandledRejection = (window as any).posthogErrorWrappingFunctions.wrapUnhandledRejection\n\n if (!wrapOnError || !wrapUnhandledRejection) {\n logger.error(LOGGER_PREFIX + ' failed to load error wrapping functions - cannot start')\n return\n }\n\n try {\n this.unwrapOnError = wrapOnError(this.captureException.bind(this))\n this.unwrapUnhandledRejection = wrapUnhandledRejection(this.captureException.bind(this))\n } catch (e) {\n logger.error(LOGGER_PREFIX + ' failed to start', e)\n this.stopCapturing()\n }\n }\n\n private stopCapturing() {\n this.unwrapOnError?.()\n this.unwrapUnhandledRejection?.()\n }\n\n afterDecideResponse(response: DecideResponse) {\n const autocaptureExceptionsResponse = response.autocaptureExceptions\n\n // store this in-memory in case persistence is disabled\n this.remoteEnabled = !!autocaptureExceptionsResponse || false\n this._endpointSuffix = isObject(autocaptureExceptionsResponse)\n ? autocaptureExceptionsResponse.endpoint || BASE_ERROR_ENDPOINT\n : BASE_ERROR_ENDPOINT\n\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE]: this.remoteEnabled,\n })\n // when we come to moving the endpoint to not /e/\n // we'll want that to persist between startup and decide response\n // TODO: once BASE_ENDPOINT is no longer /e/ this can be removed\n this.instance.persistence.register({\n [EXCEPTION_CAPTURE_ENDPOINT]: this._endpointSuffix,\n })\n }\n\n this.startIfEnabled()\n }\n\n captureException(errorProperties: Properties) {\n const posthogHost = this.instance.requestRouter.endpointFor('ui')\n\n errorProperties.$exception_personURL = `${posthogHost}/project/${\n this.instance.config.token\n }/person/${this.instance.get_distinct_id()}`\n\n this.sendExceptionEvent(errorProperties)\n }\n\n /**\n * :TRICKY: Make sure we batch these requests\n */\n sendExceptionEvent(properties: { [key: string]: any }) {\n this.instance.capture('$exception', properties, {\n _noTruncate: true,\n _batchKey: 'exceptionEvent',\n _url: this.endpoint,\n })\n }\n}\n"]}
@@ -58,7 +58,9 @@ export function createEventProcessor(_posthog, _a) {
58
58
  // we take the URL from the exception observer
59
59
  // so that when we add error specific URL for ingestion
60
60
  // these errors are sent there too
61
- _posthog.capture('$exception', data, { _url: ((_f = _posthog.exceptionObserver) === null || _f === void 0 ? void 0 : _f.endpoint) || BASE_ERROR_ENDPOINT });
61
+ _posthog.capture('$exception', data, {
62
+ _url: ((_f = _posthog.exceptionObserver) === null || _f === void 0 ? void 0 : _f.endpoint) || _posthog.requestRouter.endpointFor('api', BASE_ERROR_ENDPOINT),
63
+ });
62
64
  return event;
63
65
  };
64
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sentry-integration.js","sourceRoot":"","sources":["../../../src/extensions/sentry-integration.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integrate Sentry with PostHog. This will add a direct link to the person in Sentry, and an $exception event in PostHog\n *\n * ### Usage\n *\n * Sentry.init({\n * dsn: 'https://example',\n * integrations: [\n * new posthog.SentryIntegration(posthog)\n * ]\n * })\n *\n * @param {Object} [posthog] The posthog object\n * @param {string} [organization] Optional: The Sentry organization, used to send a direct link from PostHog to Sentry\n * @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry\n * @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)\n */\n\nimport { PostHog } from '../posthog-core'\nimport { SeverityLevel } from '../types'\nimport { BASE_ERROR_ENDPOINT } from './exception-autocapture'\n\n// NOTE - we can't import from @sentry/types because it changes frequently and causes clashes\n// We only use a small subset of the types, so we can just define the integration overall and use any for the rest\n\n// import {\n// Event as _SentryEvent,\n// EventProcessor as _SentryEventProcessor,\n// Hub as _SentryHub,\n// Integration as _SentryIntegration,\n// SeverityLevel as _SeverityLevel,\n// IntegrationClass as _SentryIntegrationClass,\n// } from '@sentry/types'\n\n// Uncomment the above and comment the below to get type checking for development\n\ntype _SentryEvent = any\ntype _SentryEventProcessor = any\ntype _SentryHub = any\n\ninterface _SentryIntegrationClass {\n name: string\n setupOnce(addGlobalEventProcessor: (callback: _SentryEventProcessor) => void, getCurrentHub: () => _SentryHub): void\n}\n\ninterface _SentryIntegration {\n name: string\n processEvent(event: _SentryEvent): _SentryEvent\n}\n\ninterface SentryExceptionProperties {\n $sentry_event_id: any\n $sentry_exception: any\n $sentry_exception_message: any\n $sentry_exception_type: any\n $sentry_tags: any\n $sentry_url?: string\n}\n\nexport type SentryIntegrationOptions = {\n organization?: string\n projectId?: number\n prefix?: string\n /**\n * By default, only errors are sent to PostHog. You can set this to '*' to send all events.\n * Or to an error of SeverityLevel to only send events matching the provided levels.\n * e.g. ['error', 'fatal'] to send only errors and fatals\n * e.g. ['error'] to send only errors -- the default when omitted\n * e.g. '*' to send all events\n */\n severityAllowList?: SeverityLevel[] | '*'\n}\n\nconst NAME = 'posthog-js'\n\nexport function createEventProcessor(\n _posthog: PostHog,\n { organization, projectId, prefix, severityAllowList = ['error'] }: SentryIntegrationOptions = {}\n): (event: _SentryEvent) => _SentryEvent {\n return (event) => {\n const shouldProcessLevel = severityAllowList === '*' || severityAllowList.includes(event.level as SeverityLevel)\n if (!shouldProcessLevel || !_posthog.__loaded) return event\n if (!event.tags) event.tags = {}\n\n const personUrl = _posthog.requestRouter.endpointFor(\n 'ui',\n `/project/${_posthog.config.token}/person/${_posthog.get_distinct_id()}`\n )\n event.tags['PostHog Person URL'] = personUrl\n if (_posthog.sessionRecordingStarted()) {\n event.tags['PostHog Recording URL'] = _posthog.get_session_replay_url({ withTimestamp: true })\n }\n\n const exceptions = event.exception?.values || []\n\n const data: SentryExceptionProperties & {\n // two properties added to match any exception auto-capture\n // added manually to avoid any dependency on the lazily loaded content\n $exception_message: any\n $exception_type: any\n $exception_personURL: string\n $exception_level: SeverityLevel\n $level: SeverityLevel\n } = {\n // PostHog Exception Properties,\n $exception_message: exceptions[0]?.value || event.message,\n $exception_type: exceptions[0]?.type,\n $exception_personURL: personUrl,\n $exception_level: event.level,\n // Sentry Exception Properties\n $sentry_event_id: event.event_id,\n $sentry_exception: event.exception,\n $sentry_exception_message: exceptions[0]?.value || event.message,\n $sentry_exception_type: exceptions[0]?.type,\n $sentry_tags: event.tags,\n $level: event.level,\n }\n\n if (organization && projectId) {\n data['$sentry_url'] =\n (prefix || 'https://sentry.io/organizations/') +\n organization +\n '/issues/?project=' +\n projectId +\n '&query=' +\n event.event_id\n }\n\n // we take the URL from the exception observer\n // so that when we add error specific URL for ingestion\n // these errors are sent there too\n _posthog.capture('$exception', data, { _url: _posthog.exceptionObserver?.endpoint || BASE_ERROR_ENDPOINT })\n\n return event\n }\n}\n\n// V8 integration - function based\nexport function sentryIntegration(_posthog: PostHog, options?: SentryIntegrationOptions): _SentryIntegration {\n const processor = createEventProcessor(_posthog, options)\n return {\n name: NAME,\n processEvent(event) {\n return processor(event)\n },\n }\n}\n// V7 integration - class based\nexport class SentryIntegration implements _SentryIntegrationClass {\n name: string\n\n setupOnce: (\n addGlobalEventProcessor: (callback: _SentryEventProcessor) => void,\n getCurrentHub: () => _SentryHub\n ) => void\n\n constructor(\n _posthog: PostHog,\n organization?: string,\n projectId?: number,\n prefix?: string,\n /**\n * By default, only errors are sent to PostHog. You can set this to '*' to send all events.\n * Or to an error of SeverityLevel to only send events matching the provided levels.\n * e.g. ['error', 'fatal'] to send only errors and fatals\n * e.g. ['error'] to send only errors -- the default when omitted\n * e.g. '*' to send all events\n */\n severityAllowList?: SeverityLevel[] | '*'\n ) {\n // setupOnce gets called by Sentry when it intializes the plugin\n this.name = NAME\n this.setupOnce = function (addGlobalEventProcessor: (callback: _SentryEventProcessor) => void) {\n addGlobalEventProcessor(\n createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList })\n )\n }\n }\n}\n"]}
1
+ {"version":3,"file":"sentry-integration.js","sourceRoot":"","sources":["../../../src/extensions/sentry-integration.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Integrate Sentry with PostHog. This will add a direct link to the person in Sentry, and an $exception event in PostHog\n *\n * ### Usage\n *\n * Sentry.init({\n * dsn: 'https://example',\n * integrations: [\n * new posthog.SentryIntegration(posthog)\n * ]\n * })\n *\n * @param {Object} [posthog] The posthog object\n * @param {string} [organization] Optional: The Sentry organization, used to send a direct link from PostHog to Sentry\n * @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry\n * @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)\n */\n\nimport { PostHog } from '../posthog-core'\nimport { SeverityLevel } from '../types'\nimport { BASE_ERROR_ENDPOINT } from './exception-autocapture'\n\n// NOTE - we can't import from @sentry/types because it changes frequently and causes clashes\n// We only use a small subset of the types, so we can just define the integration overall and use any for the rest\n\n// import {\n// Event as _SentryEvent,\n// EventProcessor as _SentryEventProcessor,\n// Hub as _SentryHub,\n// Integration as _SentryIntegration,\n// SeverityLevel as _SeverityLevel,\n// IntegrationClass as _SentryIntegrationClass,\n// } from '@sentry/types'\n\n// Uncomment the above and comment the below to get type checking for development\n\ntype _SentryEvent = any\ntype _SentryEventProcessor = any\ntype _SentryHub = any\n\ninterface _SentryIntegrationClass {\n name: string\n setupOnce(addGlobalEventProcessor: (callback: _SentryEventProcessor) => void, getCurrentHub: () => _SentryHub): void\n}\n\ninterface _SentryIntegration {\n name: string\n processEvent(event: _SentryEvent): _SentryEvent\n}\n\ninterface SentryExceptionProperties {\n $sentry_event_id: any\n $sentry_exception: any\n $sentry_exception_message: any\n $sentry_exception_type: any\n $sentry_tags: any\n $sentry_url?: string\n}\n\nexport type SentryIntegrationOptions = {\n organization?: string\n projectId?: number\n prefix?: string\n /**\n * By default, only errors are sent to PostHog. You can set this to '*' to send all events.\n * Or to an error of SeverityLevel to only send events matching the provided levels.\n * e.g. ['error', 'fatal'] to send only errors and fatals\n * e.g. ['error'] to send only errors -- the default when omitted\n * e.g. '*' to send all events\n */\n severityAllowList?: SeverityLevel[] | '*'\n}\n\nconst NAME = 'posthog-js'\n\nexport function createEventProcessor(\n _posthog: PostHog,\n { organization, projectId, prefix, severityAllowList = ['error'] }: SentryIntegrationOptions = {}\n): (event: _SentryEvent) => _SentryEvent {\n return (event) => {\n const shouldProcessLevel = severityAllowList === '*' || severityAllowList.includes(event.level as SeverityLevel)\n if (!shouldProcessLevel || !_posthog.__loaded) return event\n if (!event.tags) event.tags = {}\n\n const personUrl = _posthog.requestRouter.endpointFor(\n 'ui',\n `/project/${_posthog.config.token}/person/${_posthog.get_distinct_id()}`\n )\n event.tags['PostHog Person URL'] = personUrl\n if (_posthog.sessionRecordingStarted()) {\n event.tags['PostHog Recording URL'] = _posthog.get_session_replay_url({ withTimestamp: true })\n }\n\n const exceptions = event.exception?.values || []\n\n const data: SentryExceptionProperties & {\n // two properties added to match any exception auto-capture\n // added manually to avoid any dependency on the lazily loaded content\n $exception_message: any\n $exception_type: any\n $exception_personURL: string\n $exception_level: SeverityLevel\n $level: SeverityLevel\n } = {\n // PostHog Exception Properties,\n $exception_message: exceptions[0]?.value || event.message,\n $exception_type: exceptions[0]?.type,\n $exception_personURL: personUrl,\n $exception_level: event.level,\n // Sentry Exception Properties\n $sentry_event_id: event.event_id,\n $sentry_exception: event.exception,\n $sentry_exception_message: exceptions[0]?.value || event.message,\n $sentry_exception_type: exceptions[0]?.type,\n $sentry_tags: event.tags,\n $level: event.level,\n }\n\n if (organization && projectId) {\n data['$sentry_url'] =\n (prefix || 'https://sentry.io/organizations/') +\n organization +\n '/issues/?project=' +\n projectId +\n '&query=' +\n event.event_id\n }\n\n // we take the URL from the exception observer\n // so that when we add error specific URL for ingestion\n // these errors are sent there too\n _posthog.capture('$exception', data, {\n _url:\n _posthog.exceptionObserver?.endpoint || _posthog.requestRouter.endpointFor('api', BASE_ERROR_ENDPOINT),\n })\n\n return event\n }\n}\n\n// V8 integration - function based\nexport function sentryIntegration(_posthog: PostHog, options?: SentryIntegrationOptions): _SentryIntegration {\n const processor = createEventProcessor(_posthog, options)\n return {\n name: NAME,\n processEvent(event) {\n return processor(event)\n },\n }\n}\n// V7 integration - class based\nexport class SentryIntegration implements _SentryIntegrationClass {\n name: string\n\n setupOnce: (\n addGlobalEventProcessor: (callback: _SentryEventProcessor) => void,\n getCurrentHub: () => _SentryHub\n ) => void\n\n constructor(\n _posthog: PostHog,\n organization?: string,\n projectId?: number,\n prefix?: string,\n /**\n * By default, only errors are sent to PostHog. You can set this to '*' to send all events.\n * Or to an error of SeverityLevel to only send events matching the provided levels.\n * e.g. ['error', 'fatal'] to send only errors and fatals\n * e.g. ['error'] to send only errors -- the default when omitted\n * e.g. '*' to send all events\n */\n severityAllowList?: SeverityLevel[] | '*'\n ) {\n // setupOnce gets called by Sentry when it intializes the plugin\n this.name = NAME\n this.setupOnce = function (addGlobalEventProcessor: (callback: _SentryEventProcessor) => void) {\n addGlobalEventProcessor(\n createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList })\n )\n }\n }\n}\n"]}
@@ -54,6 +54,7 @@ export declare class PostHog {
54
54
  _retryQueue?: RetryQueue;
55
55
  sessionRecording?: SessionRecording;
56
56
  webPerformance: DeprecatedWebPerformanceObserver;
57
+ _initialPageviewCaptured: boolean;
57
58
  _triggered_notifs: any;
58
59
  compression?: Compression;
59
60
  __request_queue: QueuedRequestOptions[];
@@ -702,6 +703,7 @@ export declare class PostHog {
702
703
  */
703
704
  clear_opt_in_out_capturing(): void;
704
705
  _is_bot(): boolean | undefined;
706
+ _captureInitialPageview(): void;
705
707
  debug(debug?: boolean): void;
706
708
  }
707
709
  export declare function init_from_snippet(): void;
@@ -213,6 +213,7 @@ var PostHog = /** @class */ (function () {
213
213
  this.__request_queue = [];
214
214
  this.__loaded = false;
215
215
  this.analyticsDefaultEndpoint = '/e/';
216
+ this._initialPageviewCaptured = false;
216
217
  this.featureFlags = new PostHogFeatureFlags(this);
217
218
  this.toolbar = new Toolbar(this);
218
219
  this.scrollManager = new ScrollManager(this);
@@ -443,8 +444,8 @@ var PostHog = /** @class */ (function () {
443
444
  // NOTE: We want to fire this on the next tick as the previous implementation had this side effect
444
445
  // and some clients may rely on it
445
446
  setTimeout(function () {
446
- if (document) {
447
- _this.capture('$pageview', { title: document.title }, { send_instantly: true });
447
+ if (_this.consent.isOptedIn()) {
448
+ _this._captureInitialPageview();
448
449
  }
449
450
  }, 1);
450
451
  }
@@ -1715,11 +1716,13 @@ var PostHog = /** @class */ (function () {
1715
1716
  var _a;
1716
1717
  this.consent.optInOut(true);
1717
1718
  this._sync_opt_out_with_persistence();
1718
- if (!isUndefined(options === null || options === void 0 ? void 0 : options.captureEventName) && !(options === null || options === void 0 ? void 0 : options.captureEventName)) {
1719
- // Don't capture if captureEventName is null or false
1720
- return;
1719
+ // Don't capture if captureEventName is null or false
1720
+ if (isUndefined(options === null || options === void 0 ? void 0 : options.captureEventName) || (options === null || options === void 0 ? void 0 : options.captureEventName)) {
1721
+ this.capture((_a = options === null || options === void 0 ? void 0 : options.captureEventName) !== null && _a !== void 0 ? _a : '$opt_in', options === null || options === void 0 ? void 0 : options.captureProperties, { send_instantly: true });
1722
+ }
1723
+ if (this.config.capture_pageview) {
1724
+ this._captureInitialPageview();
1721
1725
  }
1722
- this.capture((_a = options === null || options === void 0 ? void 0 : options.captureEventName) !== null && _a !== void 0 ? _a : '$opt_in', options === null || options === void 0 ? void 0 : options.captureProperties, { send_instantly: true });
1723
1726
  };
1724
1727
  /**
1725
1728
  * Opt the user out of data capturing and cookies/localstorage for this PostHog instance.
@@ -1782,6 +1785,12 @@ var PostHog = /** @class */ (function () {
1782
1785
  return undefined;
1783
1786
  }
1784
1787
  };
1788
+ PostHog.prototype._captureInitialPageview = function () {
1789
+ if (document && !this._initialPageviewCaptured) {
1790
+ this._initialPageviewCaptured = true;
1791
+ this.capture('$pageview', { title: document.title }, { send_instantly: true });
1792
+ }
1793
+ };
1785
1794
  PostHog.prototype.debug = function (debug) {
1786
1795
  if (debug === false) {
1787
1796
  window === null || window === void 0 ? void 0 : window.console.log("You've disabled debug mode.");