posthog-js
Version:
Posthog-js allows you to automatically capture usage and send events to PostHog.
5,263 lines • 200 kB
TypeScript
import * as _posthog_types from '@posthog/types';
import { RageclickConfig, AutocaptureConfig as AutocaptureConfig$1, SessionIdChangedCallback, DeadClicksAutoCaptureConfig, SupportedWebVitalsMetrics, Properties, CaptureResult, SurveyRenderReason, ToolbarParams, JsonType, FeatureFlagsCallback, FeatureFlagDetail, FeatureFlagResult, FeatureFlagOptions, RemoteConfigFeatureFlagCallback, IsFeatureEnabledOptions, OverrideFeatureFlagsOptions, EarlyAccessFeatureCallback, EarlyAccessFeatureStage, CaptureLogOptions, Logger, CaptureMetricOptions, PostHog as PostHog$1, PostHogConfig as PostHogConfig$1, EventName, RequestResponse, SeverityLevel, RequestQueueConfig, TreeShakeable, RequestCallback, CaptureOptions as CaptureOptions$1, Property, ResetOptions, ExceptionAutoCaptureConfig } from '@posthog/types';
export { AutocaptureCompatibleElement, AutocaptureConfig, BeforeSendFn, BeforeSendMetricFn, BootstrapConfig, CanvasMaskRegion, CaptureLogOptions, CaptureMetricOptions, CaptureOptions, CapturePageviewOptions, CaptureResult, CapturedNetworkRequest, ConfigDefaults, DeadClickCandidate, DeadClicksAutoCaptureConfig, DomAutocaptureEvents, EarlyAccessFeature, EarlyAccessFeatureCallback, EarlyAccessFeatureResponse, EarlyAccessFeatureStage, ErrorTrackingOptions, EvaluationReason, EventName, ExceptionAutoCaptureConfig, ExceptionStepsConfig, ExternalIntegrationKind, FeatureFlagDetail, FeatureFlagMetadata, FeatureFlagOptions, FeatureFlagOverrideOptions, FeatureFlagOverrides, FeatureFlagPayloadOverrides, FeatureFlagResult, FeatureFlagsCallback, Headers, HeatmapConfig, InitiatorType, IsFeatureEnabledOptions, JsonRecord, JsonType, KnownEventName, LogAttributeValue, LogAttributes, LogSeverityLevel, Logger, MaskInputOptions, MetricAttributeValue, MetricAttributes, MetricSample, MetricType, MetricsConfig, NetworkRequest, OtlpAnyValue, OtlpKeyValue, OtlpLogRecord, OtlpLogsPayload, OtlpMetricsPayload, OtlpSeverityEntry, OtlpSeverityText, OverrideFeatureFlagsOptions, PerformanceCaptureConfig, Properties, Property, RageclickConfig, RemoteConfigFeatureFlagCallback, RequestCallback, RequestQueueConfig, RequestResponse, ResetOptions, SessionIdChangedCallback, SessionRecordingCanvasOptions, SessionRecordingOptions, SessionRecordingSamplingConfig, SeverityLevel, SlimDOMOptions, SupportedWebVitalsMetrics, SurveyRenderReason, ToolbarParams, ToolbarSource, ToolbarUserIntent, ToolbarVersion } from '@posthog/types';
import * as _posthog_browser_common from '@posthog/browser-common';
import { Extension as Extension$1, Client, DisplaySurveyType, SurveyPosition, Survey, PropertyMatchType, SurveyEventWithFilters, SurveyActionType, SurveyWithTypeAndAppearance, DeepReadonly, SendRequestInit, ApiResponse, Compression, RemoteConfigResult as RemoteConfigResult$1, RemoteConfig, SessionRecordingRemoteConfig, Disposable, KeyValueStore, Listener, CapturedEventInfo, SessionContext as SessionContext$1, ExtensionToken, CaptureOptions } from '@posthog/browser-common';
export { ActionStepStringMatching, ActionStepType, BasicSurveyQuestion, Compression, ConversationsRemoteConfig, DisplaySurveyType, ErrorTrackingSuppressionRule, ErrorTrackingSuppressionRuleValue, FlagVariant, LinkSurveyQuestion, MultipleSurveyQuestion, NetworkRecordOptions, PropertyFilters, PropertyMatchType, PropertyOperator, RatingSurveyQuestion, RemoteConfig, SessionRecordingEventTrigger, SessionRecordingRemoteConfig, SessionRecordingTriggerGroup, SessionRecordingTriggerPropertyFilter, SessionRecordingUrlTrigger, Survey, SurveyActionType, SurveyAppearance, SurveyEventName, SurveyEventProperties, SurveyEventType, SurveyEventWithFilters, SurveyPosition, SurveyQuestion, SurveyQuestionBranchingType, SurveyQuestionDescriptionContentType, SurveyQuestionType, SurveySchedule, SurveyTabPosition, SurveyType, SurveyWidgetType, SurveyWithTypeAndAppearance, WidgetPosition } from '@posthog/browser-common';
import { ErrorTracking, SurveyResponseValue as SurveyResponseValue$1, SurveyPosition as SurveyPosition$1, LogSdkContext, Logger as Logger$1 } from '@posthog/core';
export { KnownUnsafeEditableEvent, LogSdkContext } from '@posthog/core';
import { createLogger } from '@posthog/browser-common/utils/logger';
import { SimpleEventEmitter } from '@posthog/browser-common/utils/simple-event-emitter';
declare const ConsentStatus: {
readonly PENDING: -1;
readonly DENIED: 0;
readonly GRANTED: 1;
};
type ConsentStatus = (typeof ConsentStatus)[keyof typeof ConsentStatus];
/**
* ConsentManager provides tools for managing user consent as configured by the application.
*/
declare class ConsentManager {
private _instance;
private _persistentStore?;
constructor(_instance: PostHog);
private get _config();
get consent(): ConsentStatus;
isOptedOut(): boolean;
isOptedIn(): boolean;
isExplicitlyOptedOut(): boolean;
isRejected(): boolean;
optInOut(isOptedIn: boolean): void;
reset(): void;
private get _storageKey();
private get _storedConsent();
private get _storage();
private _getDnt;
}
declare const SAMPLED = "sampled";
type TriggerType = 'url' | 'event';
/**
* Session recording starts in buffering mode while waiting for "flags response".
* Once the response is received, it might be disabled, active or sampled.
* When "sampled" that means a sample rate is set, and the last time the session ID rotated
* the sample rate determined this session should be sent to the server.
*/
declare const sessionRecordingStatuses: readonly ["disabled", "sampled", "active", "buffering", "paused", "lazy_loading", "awaiting_config", "missing_config", "rrweb_error"];
type SessionRecordingStatus = (typeof sessionRecordingStatuses)[number];
type ExtensionConstructor<T extends Extension> = new (instance: PostHog, ...args: any[]) => T;
interface Extension {
initialize?(): boolean | void;
/**
* Receives the full remote config fetch result. Handlers must narrow on
* `result.ok` before reading config fields, and encode their failure
* behavior explicitly in the `!result.ok` branch.
*/
onRemoteConfig?(result: RemoteConfigResult): void;
}
declare class RageClick {
clicks: {
x: number;
y: number;
timestamp: number;
}[];
thresholdPx: number;
timeoutMs: number;
clickCount: number;
disabled: boolean;
constructor(rageclickConfig: RageclickConfig | boolean);
isRageClick(x: number, y: number, timestamp: number): boolean;
}
interface AutocaptureConfig extends AutocaptureConfig$1 {
enabled: boolean;
rageclick: boolean | RageclickConfig;
maskAllElementAttributes: boolean;
maskAllText: boolean;
disableCaptureUrlHashes: boolean;
getCurrentUrl?: (defaultUrl: string) => string;
remoteRequestsDisabled: boolean;
}
interface AutocaptureConfigSource {
refresh(config: AutocaptureConfig): void;
}
declare class Autocapture implements Extension$1 {
private readonly _configSource;
readonly name: _posthog_browser_common.ExtensionToken<Autocapture>;
_initialized: boolean;
_isDisabledServerSide: boolean | null;
_hasReceivedConfigResponse: boolean;
_elementSelectors: Set<string> | null;
rageclicks: RageClick;
_elementsChainAsString: boolean;
private _client?;
private readonly _config;
private _remoteConfigSubscription?;
private _domEventHandler?;
private _copiedTextHandler?;
private _disposed;
constructor(_configSource: AutocaptureConfigSource);
setup(client: Client): void;
dispose(): void;
private _refreshConfig;
private _compileUrlPatterns;
_addDomEventHandlers(): void;
private _removeDomEventHandlers;
startIfEnabled(): void;
onRemoteConfig(result: RemoteConfigResult): void;
setElementSelectors(selectors: Set<string>): void;
getElementSelectors(element: Element | null): string[] | null;
get isEnabled(): boolean;
private _captureEvent;
isBrowserSupported(): boolean;
}
declare class SessionIdManager {
private readonly _sessionIdGenerator;
private readonly _windowIdGenerator;
private _config;
private _persistence;
private _windowId;
private _sessionId;
private readonly _window_id_storage_key;
private readonly _primary_window_exists_storage_key;
private _sessionStartTimestamp;
private _pendingBootstrapSession;
private _sessionActivityTimestamp;
private _lastPersistedActivityTimestamp;
private _lastCookieSyncTimestamp;
private _sessionIdChangedHandlers;
private readonly _sessionTimeoutMs;
private _enforceIdleTimeout;
private _beforeUnloadListener;
private _destroyed;
private _eventEmitter;
on(event: 'forcedIdleReset', handler: () => void): () => void;
constructor(instance: PostHog, sessionIdGenerator?: () => string, windowIdGenerator?: () => string);
get sessionTimeoutMs(): number;
onSessionId(callback: SessionIdChangedCallback): () => void;
private _canUseSessionStorage;
private _setWindowId;
private _getWindowId;
private _isActivityChangeBelowGranularity;
private _setSessionId;
private _useCrossTabRefreshHardening;
private _refreshSessionIdFromStorage;
private _flushPendingActivityTimestamp;
private _freshestActivityTimestamp;
private _isSessionIdleAfterCrossTabRefresh;
private _getSessionId;
resetSessionId(): void;
setBootstrapSessionId(sessionID: string, deferUntilNextSession?: boolean): boolean;
/**
* Cleans up resources used by SessionIdManager.
* Should be called when the SessionIdManager is no longer needed to prevent memory leaks.
*/
destroy(): void;
private _listenToReloadWindow;
private _sessionHasBeenIdleTooLong;
checkAndGetSessionAndWindowId(readOnly?: boolean, _timestamp?: number | null, persistenceAlreadySynced?: boolean): {
sessionId: string;
windowId: string;
sessionStartTimestamp: number;
changeReason: {
noSessionId: boolean;
activityTimeout: boolean;
sessionPastMaximumLength: boolean;
crossTabAdoption: boolean;
} | undefined;
lastActivityTimestamp: number;
};
private _resetIdleTimer;
}
/**
* Author types for messages in a conversation
*/
type MessageAuthorType = 'customer' | 'AI' | 'human';
/**
* TipTap mark types for inline formatting
*/
interface TipTapMark {
type: 'bold' | 'italic' | 'underline' | 'strike' | 'code' | 'link';
attrs?: {
href?: string;
target?: string;
[key: string]: unknown;
};
}
/**
* TipTap node representing content in the document tree
*/
interface TipTapNode {
type: string;
attrs?: Record<string, unknown>;
content?: TipTapNode[];
marks?: TipTapMark[];
text?: string;
}
/**
* TipTap document - the root node of rich content
*/
interface TipTapDoc {
type: 'doc';
content?: TipTapNode[];
}
/**
* A message in a conversation
*/
interface Message {
/**
* Unique identifier for the message
*/
id: string;
/**
* The message content as plain text (fallback)
*/
content: string;
/**
* Rich content in TipTap JSON format (preferred for rendering)
* Falls back to `content` if missing or invalid
*/
rich_content?: TipTapDoc;
/**
* Type of the message author
*/
author_type: MessageAuthorType;
/**
* Display name of the message author
*/
author_name?: string;
/**
* ISO timestamp when the message was created
*/
created_at: string;
/**
* Whether this is an internal note (not shown to customer)
*/
is_private: boolean;
}
/**
* Status of a support ticket
*/
type TicketStatus = 'new' | 'open' | 'pending' | 'on_hold' | 'resolved';
/**
* A support ticket in the conversations system
*/
interface Ticket {
/**
* Unique identifier for the ticket
*/
id: string;
/**
* Current status of the ticket
*/
status: TicketStatus;
/**
* Preview of the last message
*/
last_message?: string;
/**
* ISO timestamp of the last message
*/
last_message_at?: string;
/**
* Total number of messages in this ticket
*/
message_count: number;
/**
* ISO timestamp when the ticket was created
*/
created_at: string;
/**
* Array of messages (only present in detailed ticket view)
*/
messages?: Message[];
/**
* Number of unread messages from the team
*/
unread_count?: number;
}
/**
* Visual state of the conversations widget
*/
type ConversationsWidgetState = 'open' | 'closed';
/**
* Response from sending a message
*/
interface SendMessageResponse {
/**
* ID of the ticket this message belongs to
*/
ticket_id: string;
/**
* ID of the newly created message
*/
message_id: string;
/**
* Current status of the ticket
*/
ticket_status: TicketStatus;
/**
* ISO timestamp when the message was created
*/
created_at: string;
/**
* Number of unread messages from the team
* After customer sends a message, this is always 0
*/
unread_count: number;
}
/**
* Response from fetching messages
*/
interface GetMessagesResponse {
/**
* ID of the ticket
*/
ticket_id: string;
/**
* Current status of the ticket
*/
ticket_status: TicketStatus;
/**
* Array of messages
*/
messages: Message[];
/**
* Whether there are more messages to fetch
*/
has_more: boolean;
/**
* Number of unread messages from the team
*/
unread_count: number;
}
/**
* Response from marking messages as read
*/
interface MarkAsReadResponse {
/**
* Whether the operation was successful
*/
success: boolean;
/**
* Number of unread messages (should be 0 after marking as read)
*/
unread_count: number;
}
/**
* Options for fetching tickets list
*/
interface GetTicketsOptions {
/**
* Filter by ticket status (e.g., 'open', 'closed')
*/
status?: string;
/**
* Number of tickets to return (default: 20)
*/
limit?: number;
/**
* Pagination offset (default: 0)
*/
offset?: number;
}
/**
* Response from fetching tickets list
*/
interface GetTicketsResponse {
/**
* Total count of tickets
*/
count: number;
/**
* Array of tickets
*/
results: Ticket[];
}
/**
* Payload for restoring ticket access from a one-time token
*/
interface RestoreFromTokenPayload {
/**
* Opaque one-time restore token from email link
*/
restore_token: string;
/**
* Current browser widget session ID requesting restore
*/
widget_session_id: string;
/**
* Optional distinct ID for debugging/observability
*/
distinct_id?: string;
/**
* Optional current URL for backend observability
*/
current_url?: string;
}
type RestoreFromTokenStatus = 'success' | 'expired' | 'invalid' | 'used';
/**
* Response from restore token exchange endpoint
*/
interface RestoreFromTokenResponse {
/**
* Restore result
*/
status: RestoreFromTokenStatus;
/**
* Canonical widget session ID to use after restore
*/
widget_session_id?: string;
/**
* Migrated ticket IDs, if any
*/
migrated_ticket_ids?: string[];
/**
* Optional machine-readable backend code
*/
code?: string;
}
/**
* Payload for requesting a self-service restore link email
*/
interface RequestRestoreLinkPayload {
email: string;
request_url: string;
}
/**
* Response from self-service restore link request
*/
interface RequestRestoreLinkResponse {
ok: true;
}
/**
* User traits to send with messages
*/
interface ConversationsTraits {
name?: string | null;
email?: string | null;
[key: string]: string | number | boolean | null | undefined;
}
/**
* User-provided identification data (collected via the widget form)
*/
interface UserProvidedTraits {
name?: string;
email?: string;
}
/**
* Session context captured when creating a new ticket
*/
interface SessionContext {
/**
* URL to the session replay at the time the ticket was created
* Includes timestamp to jump to the exact moment
*/
session_replay_url?: string;
/**
* Page URL where the ticket was created
*/
current_url?: string;
}
/**
* Payload for sending a message via the conversations API
*/
interface SendMessagePayload {
/**
* Widget session ID for access control
*/
widget_session_id: string;
/**
* Distinct ID for linking to PostHog Person
*/
distinct_id: string;
/**
* The message content to send
*/
message: string;
/**
* User identification traits
*/
traits: {
name: string | null;
email: string | null;
};
/**
* Ticket ID to send the message to (null to create a new ticket)
*/
ticket_id: string | null;
/**
* Session ID captured when creating a new ticket
* Stored as a separate queryable DB field
*/
session_id?: string;
/**
* Session context captured when creating a new ticket
* Stored in a JSONField for flexibility
*/
session_context?: SessionContext;
/**
* Verified distinct_id for HMAC identity mode (requires identity_hash)
*/
identity_distinct_id?: string;
/**
* HMAC-SHA256 of identity_distinct_id using team secret_api_token
*/
identity_hash?: string;
}
type ConversationsUnavailableReason = 'disabled_by_config' | 'consent_opted_out' | 'disabled_for_toolbar' | 'remote_config_pending' | 'remote_config_failed' | 'disabled_in_project' | 'missing_token' | 'extensions_unavailable' | 'load_failed' | 'initializing' | 'not_loaded';
type attributes = {
[key: string]: string | number | true | null;
};
declare const NodeType: {
readonly Document: 0;
readonly DocumentType: 1;
readonly Element: 2;
readonly Text: 3;
readonly CDATA: 4;
readonly Comment: 5;
};
type NodeType = (typeof NodeType)[keyof typeof NodeType];
type documentNode = {
type: typeof NodeType.Document;
childNodes: serializedNodeWithId[];
compatMode?: string;
};
type documentTypeNode = {
type: typeof NodeType.DocumentType;
name: string;
publicId: string;
systemId: string;
};
type elementNode = {
type: typeof NodeType.Element;
tagName: string;
attributes: attributes;
childNodes: serializedNodeWithId[];
isSVG?: true;
needBlock?: boolean;
isCustom?: true;
};
type textNode = {
type: typeof NodeType.Text;
textContent: string;
isStyle?: true;
};
type cdataNode = {
type: typeof NodeType.CDATA;
textContent: '';
};
type commentNode = {
type: typeof NodeType.Comment;
textContent: string;
};
type serializedNode = (documentNode | documentTypeNode | elementNode | textNode | cdataNode | commentNode) & {
rootId?: number;
isShadowHost?: boolean;
isShadow?: boolean;
};
type serializedNodeWithId = serializedNode & {
id: number;
};
declare const EventType: {
readonly DomContentLoaded: 0;
readonly Load: 1;
readonly FullSnapshot: 2;
readonly IncrementalSnapshot: 3;
readonly Meta: 4;
readonly Custom: 5;
readonly Plugin: 6;
};
type EventType = (typeof EventType)[keyof typeof EventType];
declare const IncrementalSource: {
readonly Mutation: 0;
readonly MouseMove: 1;
readonly MouseInteraction: 2;
readonly Scroll: 3;
readonly ViewportResize: 4;
readonly Input: 5;
readonly TouchMove: 6;
readonly MediaInteraction: 7;
readonly StyleSheetRule: 8;
readonly CanvasMutation: 9;
readonly Font: 10;
readonly Log: 11;
readonly Drag: 12;
readonly StyleDeclaration: 13;
readonly Selection: 14;
readonly AdoptedStyleSheet: 15;
readonly CustomElement: 16;
};
type IncrementalSource = (typeof IncrementalSource)[keyof typeof IncrementalSource];
type domContentLoadedEvent = {
type: typeof EventType.DomContentLoaded;
data: unknown;
};
type loadedEvent = {
type: typeof EventType.Load;
data: unknown;
};
type fullSnapshotEvent = {
type: typeof EventType.FullSnapshot;
data: {
node: serializedNodeWithId;
initialOffset: {
top: number;
left: number;
};
};
};
type metaEvent = {
type: typeof EventType.Meta;
data: {
href: string;
width: number;
height: number;
};
};
type customEvent<T = unknown> = {
type: typeof EventType.Custom;
data: {
tag: string;
payload: T;
};
};
type pluginEvent<T = unknown> = {
type: typeof EventType.Plugin;
data: {
plugin: string;
payload: T;
};
};
type styleOMValue = {
[key: string]: styleValueWithPriority | string | false;
};
type styleValueWithPriority = [string, string];
type textMutation = {
id: number;
value: string | null;
};
type attributeMutation = {
id: number;
attributes: {
[key: string]: string | styleOMValue | null;
};
};
type removedNodeMutation = {
parentId: number;
id: number;
isShadow?: boolean;
};
type addedNodeMutation = {
parentId: number;
previousId?: number | null;
nextId: number | null;
node: serializedNodeWithId;
};
type mutationCallbackParam = {
texts: textMutation[];
attributes: attributeMutation[];
removes: removedNodeMutation[];
adds: addedNodeMutation[];
isAttachIframe?: true;
};
type mutationData = {
source: typeof IncrementalSource.Mutation;
} & mutationCallbackParam;
type mousePosition = {
x: number;
y: number;
id: number;
timeOffset: number;
};
declare const MouseInteractions: {
readonly MouseUp: 0;
readonly MouseDown: 1;
readonly Click: 2;
readonly ContextMenu: 3;
readonly DblClick: 4;
readonly Focus: 5;
readonly Blur: 6;
readonly TouchStart: 7;
readonly TouchMove_Departed: 8;
readonly TouchEnd: 9;
readonly TouchCancel: 10;
};
type MouseInteractions = (typeof MouseInteractions)[keyof typeof MouseInteractions];
declare const PointerTypes: {
readonly Mouse: 0;
readonly Pen: 1;
readonly Touch: 2;
};
type PointerTypes = (typeof PointerTypes)[keyof typeof PointerTypes];
type mouseInteractionParam = {
type: MouseInteractions;
id: number;
x?: number;
y?: number;
pointerType?: PointerTypes;
};
type mouseInteractionData = {
source: typeof IncrementalSource.MouseInteraction;
} & mouseInteractionParam;
type mousemoveData = {
source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove | typeof IncrementalSource.Drag;
positions: mousePosition[];
};
type scrollPosition = {
id: number;
x: number;
y: number;
};
type scrollData = {
source: typeof IncrementalSource.Scroll;
} & scrollPosition;
type viewportResizeDimension = {
width: number;
height: number;
};
type viewportResizeData = {
source: typeof IncrementalSource.ViewportResize;
} & viewportResizeDimension;
type inputValue = {
text: string;
isChecked: boolean;
userTriggered?: boolean;
};
type inputData = {
source: typeof IncrementalSource.Input;
id: number;
} & inputValue;
declare const MediaInteractions: {
readonly Play: 0;
readonly Pause: 1;
readonly Seeked: 2;
readonly VolumeChange: 3;
readonly RateChange: 4;
};
type MediaInteractions = (typeof MediaInteractions)[keyof typeof MediaInteractions];
type mediaInteractionParam = {
type: MediaInteractions;
id: number;
currentTime?: number;
volume?: number;
muted?: boolean;
loop?: boolean;
playbackRate?: number;
};
type mediaInteractionData = {
source: typeof IncrementalSource.MediaInteraction;
} & mediaInteractionParam;
type styleSheetAddRule = {
rule: string;
index?: number | number[];
};
type styleSheetDeleteRule = {
index: number | number[];
};
type styleSheetRuleParam = {
id?: number;
styleId?: number;
removes?: styleSheetDeleteRule[];
adds?: styleSheetAddRule[];
replace?: string;
replaceSync?: string;
};
type styleSheetRuleData = {
source: typeof IncrementalSource.StyleSheetRule;
} & styleSheetRuleParam;
declare const CanvasContext: {
readonly '2D': 0;
readonly WebGL: 1;
readonly WebGL2: 2;
};
type CanvasContext = (typeof CanvasContext)[keyof typeof CanvasContext];
type canvasMutationCommand = {
property: string;
args: Array<unknown>;
setter?: true;
};
type canvasMutationParam = {
id: number;
type: CanvasContext;
commands: canvasMutationCommand[];
} | ({
id: number;
type: CanvasContext;
} & canvasMutationCommand);
type canvasMutationData = {
source: typeof IncrementalSource.CanvasMutation;
} & canvasMutationParam;
type fontParam = {
family: string;
fontSource: string;
buffer: boolean;
descriptors?: FontFaceDescriptors;
};
type fontData = {
source: typeof IncrementalSource.Font;
} & fontParam;
type SelectionRange = {
start: number;
startOffset: number;
end: number;
endOffset: number;
};
type selectionParam = {
ranges: Array<SelectionRange>;
};
type selectionData = {
source: typeof IncrementalSource.Selection;
} & selectionParam;
type styleDeclarationParam = {
id?: number;
styleId?: number;
index: number[];
set?: {
property: string;
value: string | null;
priority: string | undefined;
};
remove?: {
property: string;
};
};
type styleDeclarationData = {
source: typeof IncrementalSource.StyleDeclaration;
} & styleDeclarationParam;
type adoptedStyleSheetParam = {
id: number;
styles?: {
styleId: number;
rules: styleSheetAddRule[];
}[];
styleIds: number[];
};
type adoptedStyleSheetData = {
source: typeof IncrementalSource.AdoptedStyleSheet;
} & adoptedStyleSheetParam;
type customElementParam = {
define?: {
name: string;
};
};
type customElementData = {
source: typeof IncrementalSource.CustomElement;
} & customElementParam;
type incrementalData = mutationData | mousemoveData | mouseInteractionData | scrollData | viewportResizeData | inputData | mediaInteractionData | styleSheetRuleData | canvasMutationData | fontData | selectionData | styleDeclarationData | adoptedStyleSheetData | customElementData;
type incrementalSnapshotEvent = {
type: typeof EventType.IncrementalSnapshot;
data: incrementalData;
};
type eventWithoutTime = domContentLoadedEvent | loadedEvent | fullSnapshotEvent | incrementalSnapshotEvent | metaEvent | customEvent | pluginEvent;
type eventWithTime = eventWithoutTime & {
timestamp: number;
delay?: number;
};
interface LazyLoadedDeadClicksAutocaptureInterface {
start: (observerTarget: Node) => void;
stop: () => void;
}
declare class DeadClicksAutocapture implements Extension {
readonly instance: PostHog;
readonly isEnabled: (dca: DeadClicksAutocapture) => boolean;
readonly onCapture?: DeadClicksAutoCaptureConfig['__onCapture'];
get lazyLoadedDeadClicksAutocapture(): LazyLoadedDeadClicksAutocaptureInterface | undefined;
private _lazyLoadedDeadClicksAutocapture;
constructor(instance: PostHog, isEnabled: (dca: DeadClicksAutocapture) => boolean, onCapture?: DeadClicksAutoCaptureConfig['__onCapture']);
onRemoteConfig(result: RemoteConfigResult): void;
startIfEnabledOrStop(): void;
private _loadScript;
private _start;
stop(): void;
}
declare class ExceptionObserver {
private _instance;
private _rateLimiter;
private _remoteEnabled;
private _config;
private _unwrapOnError;
private _unwrapUnhandledRejection;
private _unwrapConsoleError;
constructor(instance: PostHog);
private _requiredConfig;
get isEnabled(): boolean;
startIfEnabledOrStop(): void;
private _loadScript;
private _startCapturing;
private _stopCapturing;
onRemoteConfig(result: RemoteConfigResult): void;
onConfigChange(): void;
captureException(errorProperties: ErrorTracking.ErrorProperties): void;
}
/**
* Captures pageviews when selected URL components change through the history API, browser back/forward navigation,
* or hash navigation.
*/
declare class HistoryAutocapture implements Extension {
private _instance;
private _popstateListener;
private _hashchangeListener;
private _lastLocation;
constructor(instance: PostHog);
initialize(): void;
get isEnabled(): boolean;
startIfEnabled(): void;
startIfEnabledOrStop(): void;
stop(): void;
monitorHistoryChanges(): void;
private _patchHistoryMethod;
private _getCurrentLocation;
private _getCaptureOptions;
private _shouldCaptureHashChanges;
private _hasLocationChanged;
private _capturePageview;
private _setupPopstateListener;
private _setupHashchangeListener;
}
declare class TracingHeaders implements Extension {
private readonly _instance;
private _restoreXHRPatch;
private _restoreFetchPatch;
private _hostnamesForPatch;
constructor(_instance: PostHog);
initialize(): void;
private _loadScript;
private _getConfiguredHostnames;
private _syncHostnamesForPatch;
private _stopCapturing;
startIfEnabledOrStop(): void;
private _startCapturing;
}
declare class WebVitalsAutocapture {
private readonly _instance;
private _enabledServerSide;
private _initialized;
private _buffer;
private _delayedFlushTimer;
constructor(_instance: PostHog);
private get _perfConfig();
get allowedMetrics(): SupportedWebVitalsMetrics[];
get flushToCaptureTimeoutMs(): number;
get attributionMetrics(): SupportedWebVitalsMetrics[];
get useAttribution(): boolean;
get useSoftNavs(): boolean;
get _maxAllowedValue(): number;
get isEnabled(): boolean;
startIfEnabled(): void;
onRemoteConfig(result: RemoteConfigResult): void;
private get _callbackFlavor();
private _loadScript;
private _maskedURL;
private _flushToCapture;
private _addToBuffer;
private _startCapturing;
}
declare class SessionRecording implements Extension {
private readonly _instance;
_forceAllowLocalhostNetworkCapture: boolean;
private _recordingStatus;
private get _config();
private get _persistence();
private _persistFlagsOnSessionListener;
private _lazyLoadedSessionRecording;
private _sessionRecordingDisposed;
private _documentWasEverVisible;
private _onVisibilityChange;
get started(): boolean;
get status(): SessionRecordingStatus;
constructor(_instance: PostHog);
initialize(): void;
dispose({ discardBufferedEvents }?: {
discardBufferedEvents?: boolean;
}): void;
private get _isRecordingEnabled();
startIfEnabledOrStop(startReason?: SessionStartReason): void;
/**
* session recording waits until it receives remote config before loading the script
* this is to ensure we can control the script name remotely
* and because we wait until we have local and remote config to determine if we should start at all
* if start is called and there is no remote config then we wait until there is
*/
private _lazyLoadAndStart;
stopRecording(): void;
private _discardRecording;
private _resetSampling;
private _validateSampleRate;
private _persistRemoteConfig;
onRemoteConfig(result: RemoteConfigResult): void;
log(message: string, level?: 'log' | 'warn' | 'error'): void;
private get _scriptName();
private _isRemoteConfigFresh;
private _onScriptLoaded;
/**
* this is maintained on the public API only because it has always been on the public API
* if you are calling this directly you are certainly doing something wrong
* @deprecated
*/
onRRwebEmit(rawEvent: eventWithTime): void;
/**
* this ignores the linked flag config and (if other conditions are met) causes capture to start
*
* It is not usual to call this directly,
* instead call `posthog.startSessionRecording({linked_flag: true})`
* */
overrideLinkedFlag(): void;
/**
* this ignores the sampling config and (if other conditions are met) causes capture to start
*
* It is not usual to call this directly,
* instead call `posthog.startSessionRecording({sampling: true})`
* */
overrideSampling(): void;
/**
* this ignores the URL/Event trigger config and (if other conditions are met) causes capture to start
*
* It is not usual to call this directly,
* instead call `posthog.startSessionRecording({trigger: 'url' | 'event'})`
* */
overrideTrigger(triggerType: TriggerType): void;
get sdkDebugProperties(): Properties;
/**
* This adds a custom event to the session recording
*
* It is not intended for arbitrary public use - playback only displays known custom events
* And is exposed on the public interface only so that other parts of the SDK are able to use it
*
* if you are calling this from client code, you're probably looking for `posthog.capture('$custom_event', {...})`
*/
tryAddCustomEvent(tag: string, payload: any): boolean;
}
type HeatmapEventBuffer = {
[key: string]: Properties[];
} | undefined;
declare class Heatmaps implements Extension {
instance: PostHog;
rageclicks: RageClick;
_enabledServerSide: boolean;
private get _config();
_initialized: boolean;
_mouseMoveTimeout: ReturnType<typeof setTimeout> | undefined;
private _buffer;
private _flushInterval;
private _deadClicksCapture;
private _onClickHandler;
private _onMouseMoveHandler;
private _flushHandler;
private _onVisibilityChange_handler;
constructor(instance: PostHog);
initialize(): void;
get flushIntervalMilliseconds(): number;
get isEnabled(): boolean;
startIfEnabled(): void;
onRemoteConfig(result: RemoteConfigResult): void;
getAndClearBuffer(): HeatmapEventBuffer;
private _onDeadClick;
private _onVisibilityChange;
private _setupListeners;
private _removeListeners;
private _getProperties;
private _onClick;
private _onMouseMove;
private _capture;
private _flush;
}
/**
* Having Survey types in types.ts was confusing tsc
* and generating an invalid module.d.ts
* See https://github.com/PostHog/posthog-js/issues/698
*/
type SurveyCallback = (surveys: Survey[], context?: {
isLoaded: boolean;
error?: string;
}) => void;
interface SurveyElement {
text?: string;
$el_text?: string;
tag_name?: string;
href?: string;
attr_id?: string;
attr_class?: string[];
nth_child?: number;
nth_of_type?: number;
attributes?: Record<string, any>;
event_id?: number;
order?: number;
group_id?: number;
}
interface DisplaySurveyOptionsBase {
/**
* Whether to bypass the survey's targeting and display conditions.
* @default false
*/
ignoreConditions: boolean;
/**
* Whether to bypass the survey's configured popup delay.
* @default false
*/
ignoreDelay: boolean;
/**
* How the survey should be displayed.
* @default DisplaySurveyType.Popover
*/
displayType: DisplaySurveyType;
/** Additional properties to include in all survey events (shown, sent, dismissed). */
properties?: Properties;
/** Pre-filled responses by question index (0-based). Only supported for popover surveys. */
initialResponses?: Record<number, SurveyResponseValue>;
}
/** Options for displaying a survey as a popover. */
interface DisplaySurveyPopoverOptions extends DisplaySurveyOptionsBase {
displayType: typeof DisplaySurveyType.Popover;
/** Override the survey's configured position. */
position?: SurveyPosition;
/** CSS selector for the element to position the survey next to (when position is NextToTrigger). */
selector?: string;
/** When true, `survey shown` events will not be emitted automatically. */
skipShownEvent?: boolean;
}
interface DisplaySurveyInlineOptions extends DisplaySurveyOptionsBase {
displayType: typeof DisplaySurveyType.Inline;
/** CSS selector for the element where the inline survey should render. */
selector: string;
}
/** Options for `posthog.displaySurvey()`. */
type DisplaySurveyOptions = DisplaySurveyPopoverOptions | DisplaySurveyInlineOptions;
interface SurveyConfig {
/**
* Prefill survey responses from matching URL parameters.
*
* @default undefined
*/
prefillFromUrl?: boolean;
/**
* @deprecated No longer used. Surveys will automatically advance past
* prefilled questions with skipSubmitButton enabled. If partial response
* collection is enabled, partial responses for pre-filled questions will
* be submitted automatically on page load.
*/
autoSubmitIfComplete?: boolean;
/**
* @deprecated No longer used. Pre-filled responses are now sent
* immediately when partial responses are enabled, or all required
* questions have been pre-filled.
*/
autoSubmitDelay?: number;
}
type SurveyResponseValue = SurveyResponseValue$1;
interface InferredSelector {
autoData: string;
text: string | null;
excludeText?: boolean;
precision?: number;
}
interface JSONContent {
type?: string;
attrs?: Record<string, any>;
content?: JSONContent[];
marks?: {
type: string;
attrs?: Record<string, any>;
}[];
text?: string;
}
type ProductTourStepType = 'element' | 'modal' | 'survey' | 'banner';
interface ProductTourBannerConfig {
behavior: 'sticky' | 'static' | 'custom';
selector?: string;
action?: {
type: 'none' | 'link' | 'trigger_tour';
link?: string;
tourId?: string;
};
animation?: {
duration?: number;
};
}
/** Button actions available on modal steps */
type ProductTourButtonAction = 'dismiss' | 'link' | 'next_step' | 'previous_step' | 'trigger_tour';
interface ProductTourStepButton {
text: string;
action: ProductTourButtonAction;
/** URL to open when action is 'link' */
link?: string;
/** Tour ID to trigger when action is 'trigger_tour' */
tourId?: string;
}
interface ProductTourStepButtons {
primary?: ProductTourStepButton;
secondary?: ProductTourStepButton;
}
type ProductTourSurveyQuestionType = 'open' | 'rating';
interface ProductTourSurveyQuestion {
type: ProductTourSurveyQuestionType;
questionText: string;
/** Rating display type - emoji or number */
display?: 'emoji' | 'number';
/** Rating scale - 3 or 5 for emoji, 5 or 10 for number */
scale?: 3 | 5 | 10;
/** Label for low end of rating scale (e.g., "Not likely") */
lowerBoundLabel?: string;
/** Label for high end of rating scale (e.g., "Very likely") */
upperBoundLabel?: string;
submitButtonText?: string;
backButtonText?: string;
}
interface ProductTourStep {
id: string;
type: ProductTourStepType;
selector?: string;
progressionTrigger: 'button' | 'click';
content: JSONContent | null;
/** Pre-rendered HTML content from the editor. If present, SDK should use this instead of rendering from JSONContent. */
contentHtml?: string;
/** Inline survey question config - if present, this is a survey step */
survey?: ProductTourSurveyQuestion;
/** ID of the auto-created survey for this step (set by backend) */
linkedSurveyId?: string;
/** ID of the survey question (set by backend, used for event tracking) */
linkedSurveyQuestionId?: string;
/** Enhanced element data for more reliable lookup at runtime */
inferenceData?: InferredSelector;
/** Use CSS selector instead of inference. Defaults to false (use inference). */
useManualSelector?: boolean;
/** Maximum tooltip width in pixels (defaults to 320px) */
maxWidth?: number;
/** Position for modal/survey steps (defaults to middle_center) */
modalPosition?: SurveyPosition$1;
/** Button configuration for modal steps */
buttons?: ProductTourStepButtons;
/** Banner configuration (only for banner steps) */
bannerConfig?: ProductTourBannerConfig;
/** translation data for this tour step */
translations?: Record<string, ProductTourStepTranslation>;
}
/** all translatable content for a given tour step */
interface ProductTourStepTranslation {
content?: ProductTourStep['content'];
contentHtml?: ProductTourStep['contentHtml'];
buttons?: {
primary?: Pick<ProductTourStepButton, 'text'>;
secondary?: Pick<ProductTourStepButton, 'text'>;
};
survey?: Pick<ProductTourSurveyQuestion, 'questionText' | 'lowerBoundLabel' | 'upperBoundLabel' | 'submitButtonText' | 'backButtonText'>;
}
/** maps to main repo EffectiveProductTourType */
type ProductTourType = 'tour' | 'announcement' | 'banner';
interface ProductTourWaitPeriod {
days: number;
types: ProductTourType[];
}
interface ProductTourConditions {
url?: string;
urlMatchType?: PropertyMatchType;
selector?: string;
autoShowDelaySeconds?: number;
events?: {
values: SurveyEventWithFilters[];
} | null;
cancelEvents?: {
values: SurveyEventWithFilters[];
} | null;
actions?: {
values: SurveyActionType[];
} | null;
linkedFlagVariant?: string;
deviceTypes?: string[];
seenTourWaitPeriod?: ProductTourWaitPeriod;
}
interface ProductTourAppearance {
backgroundColor?: string;
textColor?: string;
buttonColor?: string;
borderRadius?: number;
buttonBorderRadius?: number;
borderColor?: string;
fontFamily?: string;
boxShadow?: string;
showOverlay?: boolean;
whiteLabel?: boolean;
/** defaults to true, auto-set to false for announcements/banners */
dismissOnClickOutside?: boolean;
zIndex?: number;
}
type ProductTourDisplayFrequency = 'show_once' | 'until_interacted' | 'always';
interface ProductTour {
id: string;
name: string;
description?: string;
tour_type: ProductTourType;
auto_launch?: boolean;
start_date: string | null;
end_date: string | null;
current_iteration?: number;
conditions?: ProductTourConditions;
appearance?: ProductTourAppearance;
steps: ProductTourStep[];
internal_targeting_flag_key?: string;
linked_flag_key?: string;
display_frequency?: ProductTourDisplayFrequency;
disable_image_preload?: boolean;
}
type ProductTourCallback = (tours: ProductTour[], context?: {
isLoaded: boolean;
error?: string;
}) => void;
type ProductTourSelectorError = 'not_found' | 'multiple_matches' | 'not_visible';
type ProductTourDismissReason = 'user_clicked_skip' | 'user_clicked_outside' | 'escape_key' | 'element_unavailable' | 'container_unavailable';
type ProductTourRenderReason = 'auto' | 'api' | 'trigger' | 'event';
declare const DEFAULT_PRODUCT_TOUR_APPEARANCE: Required<ProductTourAppearance>;
interface ShowTourOptions {
reason?: ProductTourRenderReason;
enableStrictValidation?: boolean;
}
declare const ProductTourEventName: {
readonly SHOWN: "product tour shown";
readonly DISMISSED: "product tour dismissed";
readonly COMPLETED: "product tour completed";
readonly STEP_SHOWN: "product tour step shown";
readonly STEP_COMPLETED: "product tour step completed";
readonly BUTTON_CLICKED: "product tour button clicked";
readonly STEP_SELECTOR_FAILED: "product tour step selector failed";
readonly BANNER_CONTAINER_SELECTOR_FAILED: "product tour banner container selector failed";
readonly BANNER_ACTION_CLICKED: "product tour banner action clicked";
};
type ProductTourEventName = (typeof ProductTourEventName)[keyof typeof ProductTourEventName];
declare const ProductTourEventProperties: {
readonly TOUR_ID: "$product_tour_id";
readonly TOUR_NAME: "$product_tour_name";
readonly TOUR_ITERATION: "$product_tour_iteration";
readonly TOUR_RENDER_REASON: "$product_tour_render_reason";
readonly TOUR_STEP_ID: "$product_tour_step_id";
readonly TOUR_STEP_ORDER: "$product_tour_step_order";
readonly TOUR_STEP_TYPE: "$product_tour_step_type";
readonly TOUR_DISMISS_REASON: "$product_tour_dismiss_reason";
readonly TOUR_BUTTON_TEXT: "$product_tour_button_text";
readonly TOUR_BUTTON_ACTION: "$product_tour_button_action";
readonly TOUR_BUTTON_LINK: "$product_tour_button_link";
readonly TOUR_BUTTON_TOUR_ID: "$product_tour_button_tour_id";
readonly TOUR_STEPS_COUNT: "$product_tour_steps_count";
readonly TOUR_STEP_SELECTOR: "$product_tour_step_selector";
readonly TOUR_STEP_SELECTOR_FOUND: "$product_tour_step_selector_found";
readonly TOUR_STEP_ELEMENT_TAG: "$product_tour_step_element_tag";
readonly TOUR_STEP_ELEMENT_ID: "$product_tour_step_element_id";
readonly TOUR_STEP_ELEMENT_CLASSES: "$product_tour_step_element_classes";
readonly TOUR_STEP_ELEMENT_TEXT: "$product_tour_step_element_text";
readonly TOUR_ERROR: "$product_tour_error";
readonly TOUR_MATCHES_COUNT: "$product_tour_matches_count";
readonly TOUR_FAILURE_PHASE: "$product_tour_failure_phase";
readonly TOUR_WAITED_FOR_ELEMENT: "$product_tour_waited_for_element";
readonly TOUR_WAIT_DURATION_MS: "$product_tour_wait_duration_ms";
readonly TOUR_BANNER_SELECTOR: "$product_tour_banner_selector";
readonly TOUR_LINKED_SURVEY_ID: "$product_tour_linked_survey_id";
readonly USE_MANUAL_SELECTOR: "$use_manual_selector";
readonly INFERENCE_DATA_PRESENT: "$inference_data_present";
readonly TOUR_LAST_SEEN_DATE: "$product_tour_last_seen_date";
readonly TOUR_TYPE: "$product_tour_type";
};
type ProductTourEventProperties = (typeof ProductTourEventProperties)[keyof typeof ProductTourEventProperties];
declare class PostHogProductTours implements Extension {
private _instance;
private _productTourManager;
private _cachedTours;
private get _persistence();
constructor(instance: PostHog);
initialize(): void;
onRemoteConfig(result: RemoteConfigResult): void;
loadIfEnabled(): void;
private _loadScript;
private _startProductTours;
getProductTours(callback: ProductTourCallback, forceReload?: boolean): void;
getActiveProductTours(callback: ProductTourCallback): void;
showProductTour(tourId: string): void;
previewTour(tour: ProductTour): void;
dismissProductTour(): void;
nextStep(): void;
previousStep(): void;
clearCache(): void;
resetTour(tourId: string): void;
resetAllTours(): void;
cancelPendingTour(tourId: string): void;
}
declare class SiteApps implements Extension {
private _instance;
apps: Record<string, SiteApp>;
private _stopBuffering?;
private _bufferedInvocations;
private _siteAppElementPatchCount;
private _restoreSiteAppElementPatches?;
constructor(_instance: PostHog);
get isEnabled(): boolean;
private _eventCollector;
get siteAppLoaders(): SiteAppLoader[] | undefined;
initialize(): void;
globalsForEvent(event: CaptureResult): SiteAppGlobals;
private _prepareElementForSiteApp;
private _patchSiteAppElementInsertionMethods;
private _releaseSiteAppElementPatches;
private _runWithPreparedSiteAppElements;
setupSiteApp(loader: SiteAppLoader): void;
private _setupSiteApps;
private _onCapturedEvent;
onRemoteConfig(result: RemoteConfigResult): void;
}
declare class SurveyManager {
private _posthog;
private _surveyInFocus;
private _surveyTimeouts;
private _widgetSelectorListeners;
private _renderedTargets;
private _prefillHandledSurveys;
private _automaticDisplayDispose?;
private _currentLanguage;
private _surveyIsRendered;
private _languageChangeListener;
private _unsubscribeFeatureFlags;
private _surveyPopupProps;
private _displayOptions;
constructor(posthog: PostHog);
private _onLanguageChange;
private get _featureFlags();
private _applyDisplayOverrides;
handlePageUnload: () => void;
private _clearSurveyTimeout;
/**
* cancel a "pending" survey, i.e. one that is waiting to be displayed in
* the _surveyTimeouts queue
*/
cancelSurvey(surveyId: string): void;
setAutomaticDisplayDispose(dispose: () => void): void;
dispose(): void;
/**
* `resumeDelayFromActivation` is internal to the display loop: a survey armed by an
* event/action trigger resumes its popup delay from when the trigger fired, so navigating
* mid-delay does not restart the countdown. An explicit `displaySurvey()` call carries its own
* `ignoreDelay` option instead, so it must always honor the full configured delay.
*/
handlePopoverSurvey: (surveyParam: Survey, options?: DisplaySurveyPopoverOptions, { resumeDelayFromActivation }?: {
resumeDelayFromActivation?: boolean;
}) => void;
private _handleWidget;
private _detachWidgetSelectorListener;
private _removeWidgetSelectorListener;
private _isWidgetSurveyOpen;
private _manageWidgetSelectorListener;
/**
* Sorts surveys by their appearance delay in ascending order. If a survey does not have an appearance delay,
* it is considered to have a delay of 0.
* @param surveys
* @returns The surveys sorted by their appearance delay
*/
private _sortSurveysByAppearanceDelay;
renderPopover: (survey: Survey) => void;
renderSurvey: (survey: Survey, selector: Element, properties?: Properties) => void;
private _translateSurveyForRendering;
private _handleUrlPrefill;
/**
* On load, capture a response for prefilled questions only when:
* 1) the survey is complete, OR
* 2) partial responses are enabled AND the skipped questions were set to auto-submit.
*/
private _autoSubmitPrefilledResponses;
/**
* process prefilled responses for non-hosted surveys
*
* @returns boolean, true if the survey is completed
*/
private _handleInitialResponses;
private _processPrefillData;
private _isSurveyFeatureFlagEnabled;
private _isSurveyConditionMatched;
private _internalFlagCheckSatisfied;
checkSurveyEligibility(survey: Survey): {
eligible: boolean;
reason?: string;
};
/**
* Renderability = eligibility (running, type, flags, wait period, already-seen) plus the
* survey's event/action activation trigger. Used by the programmatic `canRenderSurvey` /
* `canRenderSurveyAsync` checks so they match the display loop.
*
* The trigger is intentionally kept out of `checkSurveyEligibility`: that method is also
* used by the explicit `displaySurvey` path, and the trigger state only lives in memory
* (a reload clears it, server-side events never set it). Gating eligibility on it would
* make explicit `displaySurvey('id')` calls silently show nothing.
*/
checkSurveyRenderability(survey: Survey): {
eligible: boolean;
reason?: string;
};
/**
* Surveys can be activated by events or actions. This method checks if the survey has events and actions,
* and if so, it checks if the survey has been activated.
* @param survey
*/
private _hasActionOrEventTriggeredSurvey;
private _checkFlags;
/**
* The full predicate for "should this survey display right now": eligibility (running,
* type, linked/targeting/internal flags, wait period, already-seen) plus the URL/device/
* selector conditions, the event/action trigger, and any feature-flag dependencies.
*
* Shared by the display loop and re-checked when a popover's delay timer fires, so a
* survey that became ineligible *during* the delay (e.g. an identify() reloaded flags and
* the internal targeting flag is now false) is not shown. Note this is purely an AND gate:
* adding it can only ever suppress a display, never cause an extra one.
*/
private _shouldDisplaySurvey;
getActiveMatchingSurveys: (callback: SurveyCallback, forceReload?: boolean) => void;
callSurveysAndEvaluateDisplayLogic: (forceReload?: boolean) => void;
private _addSurveyToFocus;
private _removeSurveyFromDom;
private _removeSurveyFromFocus;
getTestAPI(): {
addSurveyToFocus: (survey: Pick<Survey, "id">) => void;
removeSurveyFromFocus: (survey: SurveyWithTypeAndAppearance) => void;
surveyInFocus: string | null;
surveyTimeouts: Map<string, number>;
handleWidget: (survey: Survey) => void;
handlePopoverSurvey: (surveyParam: Survey, options?: DisplaySurveyPopoverOptions, { resumeDelayFromActivation }?: {
resumeDelayFromActivation?: boolean;
}) => void;
manageWidgetSelectorListener: (survey: Survey, selector: string) => void;
sortSurveysByAppearanceDelay: (surveys: Survey[]) => Survey[];
checkFlags: (survey: Survey) => boolean;
isSurveyFeatureFlagEnabled: (flagKey: string | null, flagVariant?: string | undefined) => boolean;
onLanguageChange: () => void;
currentLanguage: string | null;
surveyIsRendered: boolean;
};
}
declare class ActionMatcher {
private readonly _instance?;
private readonly _actionRegistry;
private readonly _actionEvents;
private _debugEventEmitter;
private _captureHookUnsubscribe?;
constructor(_instance?: PostHog | undefined);
init(): void;
dispose(): void;
register(actions: SurveyActionType[]): void;
replace(actions: SurveyActionType[]): void;
on(eventName: string, eventPayload?: CaptureResult): void;
_addActionHook(callback: (actionName: string, eventPayload?: any) => void): void;
private _checkAction;
onAction(event: 'actionCaptured', cb: (...args: any[]) => void): () => void;
private _checkStep;
private _checkStepEvent;
private _checkStepUrl;
private _checkStepElement;
private _checkStepHref;
private _checkStepText;
private _checkStepSelector;
private _getElementsList;
private _checkStepProperties;
}
/**
* Interface for items that can be triggered by events/actions.
* Both Survey and ProductTour implement this interface.
*/
interface EventTriggerable {
id: string;
conditions?: {
events?: {
repeatedActivation?: boolean;
values: SurveyEventWithFilters[];
} | null;
cancelEvents?: {
values: SurveyEventWithFilters[];
} | null;
actions?: {
values: SurveyActionType[];
} | null;
} | null;
}
/**
* What a captured lifecycle event (shown / dismissed / sent) does to an already-activated item:
* - `consume`: it's done — drop it from both the in-memory and persisted sets.
* - `persist`: it was shown and should survive a reload — move it from memory into persistence.
* - `ignore`: no transition for this item on this event.
*/
type ActivationOutcome = 'consume' | 'persist' | 'ignore';
/**
* Abstract base class for receiving events and matching them to triggerable items.
* Subclasses implement type-specific behavior for surveys and product tours.
*/
declare abstract class EventReceiver<T extends EventTriggerable> {
protected _eventToItems: Map<string, string[]>;
protected _cancelEventToItems: Map<string, string[]>;
protected readonly _actionToItems: Map<string, string[]>;
protected _actionMatcher?: ActionMatcher | null;
protected readonly _instance?: PostHog;
/**
* Items armed by an event or action but not yet shown live here, in memory only.
* They are intentionally NOT persisted, so they do not survive a page reload: an
* event trigger only displays an item in the session the event fired in. Once an
* item is shown, surviving items are promoted into persistence (see `onEvent`) so
* a reload re-reads and re-displays them until the user interacts — but that
* persisted activation is scoped to the triggering session (see
* `_getPersistedActivatedIds`), so it does not leak into a brand-new session where
* the trigger never fired.
*/
private _pendingActivatedItems;
private _captureHookUnsubscribe?;
private _sessionIdUnsubscribe?;
constructor(instance: PostHog);
protected abstract _getActivatedKey(): string;
/** Persistence key under which the session id of the persisted activation set is stamped. */
protected abstract _getActivatedSessionKey(): string;
protected abstract _getShownEventName(): string;
protected abstract _getItems(callback: (items: T[]) => void): void;
protected abstract _cancelPendingItem(itemId: string): void;
protected abstract _getLogger(): ReturnType<typeof createLogger>;
protected abstract _setActivatedItems(eligibleItems: string[]): void;
/** Persist the session id the current activation set belongs to. */
protected abstract _setActivatedSession(sessionId: string): void;
/** Forget the persisted session stamp. */
protected abstract _clearActivatedSession(): void;
/** Check if item is permanently ineligible (e.g. completed/dismissed). Skip adding to activated list. */
protected abstract _isItemPermanentlyIneligible(itemId?: string): boolean;
/**
* Decide what a captured lifecycle `event` does to an already-activated `itemId`. Most items are
* consumed when shown (so they only reappear when their trigger fires again). Surveys keep
* non-repeatable ones activated — promoting them to session-scoped persistence on shown — until the
* user dismisses or answers them, so an event-triggered survey survives a reload within the
* triggering session (but not a brand-new session) until it's actually interacted with.
*/
protected abstract _activationOutcome(event: string, itemId: string): ActivationOutcome;
/**
* Whether an item armed by a trigger should be persisted immediately (session-scoped)
* instead of kept in memory until it is shown. Overridden by receivers whose items carry a
* display delay that must survive a navigation, so the delay can resume from where it left
* off on the next page. Default: keep in memory, so the arming is page-scoped and an
* exit-intent-style trigger cannot leak an armed item onto a later page load.
*/
protected _shouldPersistArmedActivation(_itemId: string): boolean;
/**
* Persistence key under which per-item activation timestamps are read from, or null for
* receivers that don't track them. Used to resume a display delay across navigations. Writes
* go through `_writeActivationTimestamps` / `_clearActivationTimestampsStore` so the register
* sink always resolves to a literal key constant.
*/
protected _getActivationTimestampsKey(): string | null;
/** Persist the activation timestamp map. Overridden by receivers that track timestamps. */
protected _writeActivationTimestamps(_timestamps: Record<string, number>): void;
/** Forget the whole activation timestamp map. Overridden by receivers that track timestamps. */
protected _clearActivationTimestampsStore(): void;
private _doesEventMatchFilter;
private _buildEventToItemMap;
/**
* build a map of (Event1) => [Item1, Item2, Item3]
* used for items that should be [activated|cancelled] by Event1
*/
private _getMatchingItems;
register(items: T[]): void;
replace(items: T[]): void;
private _register;
private _setupActionBasedItems;
private _mergeItemMaps;
private _setupEventBasedItems;
onEvent(event: string, eventPayload?: CaptureResult): void;
onAction(actionName: string): void;
/**
* Arm items. Most are held in memory only (not persisted) until they are shown, so their
* arming is page-scoped. Items that opt in via `_shouldPersistArmedActivation` (those with a
* display delay) are persisted right away and stamped with the activation time, so the delay
* survives a navigation and resumes from the elapsed time on the next page.
*/
private _activateItems;
/**
* Move an in-memory activation into persistence so it survives a page reload within the
* triggering session. The set is (re)stamped with the current session id; reading it back
* via `_getPersistedActivatedIds` discards it once the session rolls over. Because we build
* on top of the session-scoped read, a stale set left over from a previous session is
* dropped here rather than accumulated.
*/
private _persistActivation;
/** Drop items from both the in-memory and persisted activation sets. */
private _deactivateItems;
/** The raw persisted activation timestamps as stored, ignoring session scoping. */
private _getRawActivationTimestamps;
/**
* Stamp when an item enters persisted activation, so a resumed display delay can be computed
* from the elapsed time on a later page load. Repeated triggers do not call this method because
* `_persistActivation` returns false while the current activation is still live.
*/
private _recordActivationTimestamp;
/** Drop the activation timestamps for the given items. */
private _clearActivationTimestamps;
/** Forget all activation timestamps (e.g. on reset or a session rollover). */
private _clearAllActivationTimestamps;
/**
* The time (epoch ms) an item was armed by its trigger, or undefined if none is recorded.
* Session-scoped: a timestamp is only honored while its activation is still live for the
* current session, so a stale entry left in persistence cannot resurrect an expired delay.
*/
getActivationTimestamp(itemId: string): number | undefined;
/** The raw persisted set as stored, ignoring session scoping. */
private _getRawPersistedActivatedIds;
/**
* The persisted activations that still belong to the current session. A persisted activation
* is scoped to the session the item was shown in: an event/action trigger only earns a display
* in the session it fired in, so once the session rolls over the activation is stale and must
* not silently re-display the item in a brand-new session where the trigger never fired.
*/
private _getPersistedActivatedIds;
/** Stamp the persisted activation set with the current session id. */
private _stampActivationSession;
/** Forget the session stamp once nothing is persisted under it. */
private _clearActivationSession;
/**
* Drop a persisted activation once the session it was stamped under is no longer current.
* Fired on session rotation (idle timeout, max length, cross-tab adoption) — the cases the
* read-only session read on the display path cannot observe. Pending timers must also be
* cancelled so a fresh trigger in the new session starts its full delay from the new timestamp.
*/
private _onSessionIdChanged;
getActivatedIds(): string[];
/**
* Clear all activations. Called on `posthog.reset()` so a logout or account switch
* (without a full page reload) does not leave an event-armed item live for the next
* user — the in-memory set would otherwise survive `persistence.clear()`.
*/
dispose(): void;
reset(): void;
getEventToItemsMap(): Map<string, string[]>;
_getActionMatcher(): ActionMatcher | null | undefined;
}
declare class SurveyEventReceiver extends EventReceiver<Survey> {
constructor(instance: PostHog);
protected _getActivatedKey(): string;
protected _getActivatedSessionKey(): string;
protected _getActivationTimestampsKey(): string;
protected _writeActivationTimestamps(timestamps: Record<string, number>): void;
protected _clearActivationTimestampsStore(): void;
/**
* A survey with a popup delay must survive navigation so the delay resumes from the recorded
* activation time on the next page instead of restarting from zero. Surveys without a delay
* keep the in-memory arming, so an exit-intent trigger does not surface them on a later page.
*/
protected _shouldPersistArmedActivation(itemId: string): boolean;
protected _getShownEventName(): string;
protected _getItems(callback: (items: Survey[]) => void): void;
protected _cancelPendingItem(itemId: string): void;
protected _getLogger(): ReturnType<typeof createLogger>;
protected _setActivatedItems(eligibleItems: string[]): void;
protected _setActivatedSession(sessionId: string): void;
protected _clearActivatedSession(): void;
protected _isItemPermanentlyIneligible(): boolean;
protected _activationOutcome(event: string, itemId: string): ActivationOutcome;
getSurveys(): string[];
getEventToSurveys(): Map<string, string[]>;
}
interface SurveysConfig {
disableSurveys: boolean;
cookielessMode: boolean;
advancedEnableSurveys: boolean;
requestTimeoutMs: number;
}
interface SurveysExtensionHost {
generateSurveys?: (isSurveysEnabled: boolean) => SurveyManager;
loadExternalDependency?: (callback: (error?: unknown) => void) => void;
}
interface SurveysConfigSource {
get(): Readonly<SurveysConfig>;
isOptedOut(): boolean;
getExtensions(): SurveysExtensionHost | undefined;
createEventReceiver(): SurveyEventReceiver;
}
type SurveysClientState = Pick<Client, 'projectToken' | 'kv'>;
declare class PostHogSurveys implements Extension$1 {
private readonly _configSource;
private readonly _initialClientState?;
readonly name: _posthog_browser_common.ExtensionToken<PostHogSurveys>;
private _isSurveysEnabled?;
_surveyEventReceiver: SurveyEventReceiver | null;
private _surveyManager;
private _isInitializingSurveys;
private _surveyCallbacks;
private _getSurveysInFlightPromise;
private _lastSurveyRefreshFailedAt;
private _client?;
private _initializingClient?;
private _remoteConfigSubscription?;
private _disposed;
private _renderTimeouts;
constructor(_configSource: SurveysConfigSource, _initialClientState?: SurveysClientState | undefined);
setup(client: Client): void | Promise<void>;
dispose(): void;
private get _config();
initialize(): void;
onRemoteConfig: (result: DeepReadonly<RemoteConfigResult>) => void;
reset(): void;
loadIfEnabled(): void;
/** Helper to finalize survey initialization */
private _completeSurveyInitialization;
/** Helper to handle errors during survey loading */
private _handleSurveyLoadError;
/**
* Register a callback that runs when surveys are initialized.
* ### Usage:
*
* posthog.onSurveysLoaded((surveys) => {
* // You can work with all surveys
* console.log('All available surveys:', surveys)
*
* // Or get active matching surveys
* posthog.getActiveMatchingSurveys((activeMatchingSurveys) => {
* if (activeMatchingSurveys.length > 0) {
* posthog.renderSurvey(activeMatchingSurveys[0].id, '#survey-container')
* }
* })
* })
*
* @param {Function} callback The callback function will be called when surveys are loaded or updated.
* It receives the array of all surveys and a context object with error status.
* @returns {Function} A function that can be called to unsubscribe the listener.
*/
onSurveysLoaded(callback: SurveyCallback): () => void;
getSurveys(callback: SurveyCallback, forceReload?: boolean): void;
protected _sendSurveysRequest(path: string, init: SendRequestInit): Promise<ApiResponse>;
private _handleSurveyResponse;
/**
* Whether to kick off a background refresh of the cached definitions: the cache is stale, no
* fetch is already in flight, and we're not backing off after a recent failure.
*/
private _shouldBackgroundRefreshSurveys;
/**
* Whether the cached `$surveys` definitions have aged past their TTL. Returns false when no
* timestamp is recorded (e.g. surveys injected directly in tests) so the cache stays valid.
*/
private _isSurveyCacheStale;
private _isSurveyRefreshBackingOff;
/**
* Marks a survey as seen for the current device, mirroring the local state the SDK records
* when it shows or sends a survey itself.
*
* Use this when you display surveys through your own backend/integration (so the SDK never
* captures the `survey shown`/`sent`/`dismissed` events) and still want PostHog's display
* logic to honour the "already seen" and wait-period checks on subsequent page loads.
*
* Note: surveys configured to repeat (`schedule: 'always'` or event `repeatedActivation`)
* intentionally bypass the seen check, so marking them as seen will not stop them showing.
*
* @param surveyId The ID of the survey to mark as seen.
* @param options Optional settings. `iteration` is the survey's current iteration number, if any.
*/
markSurveyAsSeen(surveyId: string, options?: {
iteration?: number | null;
}): void;
/** Helper method to notify all registered callbacks */
private _notifySurveyCallbacks;
getActiveMatchingSurveys(callback: SurveyCallback, forceReload?: boolean): void;
private _getSurveyById;
private _checkSurveyEligibility;
private _checkSurveyRenderability;
canRenderSurvey(surveyId: string | Survey): SurveyRenderReason;
canRenderSurveyAsync(surveyId: string, forceReload: boolean): Promise<SurveyRenderReason>;
renderSurvey(surveyId: string | Survey, selector: string, properties?: Properties): void;
displaySurvey(surveyId: string, options: DisplaySurveyOptions): void;
cancelPendingSurvey(surveyId: string): void;
handlePageUnload(): void;
}
/** Browser-v1 compatibility wrapper for the shared surveys extension. */
declare class BrowserSurveys extends PostHogSurveys {
private readonly _instance;
constructor(_instance: PostHog);
protected _sendSurveysRequest(path: string, init: SendRequestInit): Promise<ApiResponse>;
}
declare class Toolbar implements Extension {
instance: PostHog;
constructor(instance: PostHog);
private _setToolbarState;
private _getToolbarState;
initialize(): boolean;
/**
* To load the toolbar, we need an access token and other state. That state comes from one of three places:
* 1. In the URL hash params
* 2. From session storage under the key `toolbarParams` if the toolbar was initialized on a previous page
*/
maybeLoadToolbar(location?: Location | undefined, localStorage?: Storage | undefined, history?: History | undefined): boolean;
private _callLoadToolbar;
loadToolbar(params?: ToolbarParams): boolean;
/** @deprecated Use "loadToolbar" instead. */
_loadEditor(params: ToolbarParams): boolean;
/** @deprecated Use "maybeLoadToolbar" instead. */
maybeLoadEditor(location?: Location | undefined, localStorage?: Storage | undefined, history?: History | undefined): boolean;
}
declare class PostHogExceptions implements Extension {
private readonly _instance;
private _suppressionRules;
private _errorPropertiesBuilder;
private _exceptionStepsBuffer;
private _exceptionStepsConfig;
constructor(instance: PostHog);
onConfigChange(): void;
onRemoteConfig(result: RemoteConfigResult): void;
private get _captureExtensionExceptions();
buildProperties(input: unknown, metadata?: {
handled?: boolean;
syntheticException?: Error;
}): ErrorTracking.ErrorProperties;
addExceptionStep(message: string, properties?: Properties): void;
sendExceptionEvent(properties: Properties): CaptureResult | undefined;
private _addBufferedExceptionSteps;
private _addDroppedExceptionStep;
private _coerceExceptionStepProperties;
private _getExceptionStepsConfig;
private _matchesSuppressionRule;
private _isExtensionException;
private _isInjectedBrowserScriptException;
private _isPostHogException;
private _isExceptionList;
}
interface WebExperimentTransform {
attributes?: {
name: string;
value: string;
}[];
selector?: string;
text?: string;
html?: string;
imgUrl?: string;
css?: string;
}
type WebExperimentUrlMatchType = 'regex' | 'not_regex' | 'exact' | 'is_not' | 'icontains' | 'not_icontains';
interface WebExperimentVariant {
conditions?: {
url?: string;
urlMatchType?: WebExperimentUrlMatchType;
utm?: {
utm_source?: string;
utm_medium?: string;
utm_campaign?: string;
utm_term?: string;
};
};
variant_name: string;
transforms: WebExperimentTransform[];
}
interface WebExperiment {
id: number;
name: string;
feature_flag_key?: string;
variants: Record<string, WebExperimentVariant>;
}
type WebExperimentsCallback = (webExperiments: WebExperiment[]) => void;
declare class WebExperiments implements Extension {
private _instance;
private _flagToExperiments?;
private get _config();
constructor(_instance: PostHog);
initialize(): void;
onFeatureFlags(flags: string[]): void;
previewWebExperiment(): void;
loadIfEnabled(): void;
getWebExperimentsAndEvaluateDisplayLogic: (forceReload?: boolean) => void;
getWebExperiments(callback: WebExperimentsCallback, forceReload: boolean, previewing?: boolean): void;
private _showPreviewWebExperiment;
private static _matchesTestVariant;
private static _matchUrlConditions;
static getWindowLocation(): Location | undefined;
private static _matchUTMConditions;
private static _logInfo;
private _applyTransforms;
_is_bot(): boolean | undefined;
}
declare class PostHogConversations implements Extension {
private _instance;
private _isConversationsEnabled?;
private _conversationsManager;
private _isInitializing;
private _remoteConfig;
private _remoteConfigSuccessful?;
private _loadFailed;
constructor(_instance: PostHog);
initialize(): void;
onRemoteConfig(result: RemoteConfigResult): void;
reset(): void;
loadIfEnabled(): void;
/** Helper to finalize conversations initialization */
private _completeInitialization;
/** Helper to handle initialization errors */
private _handleLoadError;
/**
* Show the conversations widget (button and chat panel)
*/
show(): void;
/**
* Hide the conversations widget completely (button and chat panel)
*/
hide(): void;
/**
* Check if conversations are available (enabled in remote config AND loaded)
* Use this to check if conversations API can be used.
*/
isAvailable(): boolean;
/**
* Explain why {@link isAvailable} is currently false, or null when conversations are available.
* Lets a caller that falls back to another channel record the specific cause (bundle blocked,
* disabled in the project, remote config not loaded yet, still initializing, …) rather than
* collapsing every case into a single "unavailable" signal.
*/
getUnavailableReason(): ConversationsUnavailableReason | null;
/**
* Check if the widget is currently visible (rendered and shown)
*/
isVisible(): boolean;
/**
* Send a message programmatically
* Creates a new ticket if none exists or if newTicket is true
*
* @param message - The message text to send
* @param userTraits - Optional user identification data (name, email)
* @param newTicket - If true, forces creation of a new ticket (starts new conversation)
* @returns Promise with response or null if conversations not available yet
* @note Conversations must be available first (check with isAvailable())
*
* @example
* // Send to existing or create new conversation
* const response = await posthog.conversations.sendMessage('Hello!', {
* name: 'John Doe',
* email: 'john@example.com'
* })
*
* @example
* // Force creation of a new conversation/ticket
* const newConvo = await posthog.conversations.sendMessage('Start fresh', undefined, true)
*/
sendMessage(message: string, userTraits?: UserProvidedTraits, newTicket?: boolean): Promise<SendMessageResponse | null>;
/**
* Get messages for the current or specified ticket
*
* @param ticketId - Optional ticket ID (defaults to current active ticket)
* @param after - Optional ISO timestamp to fetch messages after
* @returns Promise with messages response or null if conversations not available yet
* @note Conversations must be available first (check with isAvailable())
*
* @example
* // Get messages for current ticket
* const messages = await posthog.conversations.getMessages()
*
* // Get messages for specific ticket
* const messages = await posthog.conversations.getMessages('ticket-uuid')
*/
getMessages(ticketId?: string, after?: string): Promise<GetMessagesResponse | null>;
/**
* Mark messages as read for the current or specified ticket
*
* @param ticketId - Optional ticket ID (defaults to current active ticket)
* @returns Promise with response or null if conversations not available yet
* @note Conversations must be available first (check with isAvailable())
*
* @example
* await posthog.conversations.markAsRead()
*/
markAsRead(ticketId?: string): Promise<MarkAsReadResponse | null>;
/**
* Get list of tickets for the current widget session
*
* @param options - Optional filtering and pagination options
* @returns Promise with tickets response or null if conversations not available yet
* @note Conversations must be available first (check with isAvailable())
*
* @example
* const tickets = await posthog.conversations.getTickets({
* limit: 10,
* offset: 0,
* status: 'open'
* })
*/
getTickets(options?: GetTicketsOptions): Promise<GetTicketsResponse | null>;
/**
* Request a restore link email for previous conversations.
*
* @param email - Email address associated with previous conversations
* @returns Promise with generic success response or null if conversations unavailable
*/
requestRestoreLink(email: string): Promise<RequestRestoreLinkResponse | null>;
/**
* Redeem a restore token and relink eligible tickets to this browser session.
*
* @param restoreToken - Opaque restore token from restore email link
* @returns Promise with restore status or null if conversations unavailable
*/
restoreFromToken(restoreToken: string): Promise<RestoreFromTokenResponse | null>;
/**
* Parse and redeem `ph_conv_restore` token from the current URL.
*
* @returns Promise with restore status, or null when no token/conversations unavailable
*/
restoreFromUrlToken(): Promise<RestoreFromTokenResponse | null>;
/**
* Get the current active ticket ID
* Returns null if no conversation has been started yet or if not available
*
* @returns Ticket ID or null
* @note Safe to call before conversations are available, will return null
*
* @example
* const ticketId = posthog.conversations.getCurrentTicketId()
* if (ticketId) {
* console.log('Current ticket ID:', ticketId)
* }
*/
getCurrentTicketId(): string | null;
/**
* Get the widget session ID (persistent browser identifier)
* This ID is used for access control and stays the same across page loads
* Returns null if conversations not available yet
*
* @returns Session ID or null if not available
* @note Safe to call before conversations are available, will return null
*
* @example
* const sessionId = posthog.conversations.getWidgetSessionId()
* if (!sessionId) {
* // Conversations not available yet
* posthog.conversations.show()
* }
*/
getWidgetSessionId(): string | null;
/** @internal Called by PostHog.setIdentity() -- forwards to the manager without recursing */
_onIdentityChanged(): void;
/** @internal Called by PostHog.clearIdentity() -- forwards to the manager without recursing */
_onIdentityCleared(): void;
}
interface FeatureFlagsConfig {
readonly bootstrap: {
readonly featureFlags?: Readonly<Record<string, string | boolean>>;
readonly featureFlagPayloads?: Readonly<Record<string, JsonType>>;
};
readonly remoteRequestsDisabled: boolean;
readonly featureFlagsDisabled: boolean;
readonly onlyEvaluateSurveyFeatureFlags: boolean;
readonly deduplicateCallsPerSession: boolean;
readonly cacheTtlMs?: number;
readonly refreshIntervalMs?: number;
readonly requestTimeoutMs: number;
readonly compression?: Compression | 'best-available';
readonly evaluationContexts: readonly string[];
readonly flagKeys?: readonly string[];
}
interface FeatureFlagsConfigSource {
get(): Readonly<FeatureFlagsConfig>;
}
declare class PostHogFeatureFlags implements Extension$1 {
readonly name: _posthog_browser_common.ExtensionToken<PostHogFeatureFlags>;
_override_warning: boolean;
featureFlagEventHandlers: FeatureFlagsCallback[];
$anon_distinct_id: string | undefined;
private _client?;
private _initializingClient?;
private _logger;
private _dynamicProperties?;
private _crossTabPersistenceUnsubscribe?;
private _baseEventProperties;
private _eventPropertiesWithFlagValues;
private _reloadingHandlers;
private _hasLoadedFlags;
private _requestInFlight;
private _requestGeneration;
private _reloadingDisabled;
private _additionalReloadRequested;
private _reloadDebouncer?;
private _flagsLoadedFromRemote;
private _staleCacheRefreshTriggered;
private _consecutiveStatusZeroFailures;
private _refreshInterval?;
private _refreshIntervalMs?;
private _lastRefreshAt?;
private readonly _configSource;
private readonly _mutableConfigSource?;
private readonly _instance?;
constructor(instance: PostHog);
constructor(configSource: FeatureFlagsConfigSource);
updateConfig(config: PostHogConfig, remoteRequestsDisabled: boolean): void;
setup(client: Client): void | Promise<void>;
private _finishSetup;
private _onOnline;
private _refreshIfDue;
private _onVisibilityChange;
private _syncAutomaticRefresh;
private _scheduleNextRefresh;
private _stopAutomaticRefresh;
destroy(): void;
dispose(): void;
private _dispose;
private get _config();
private _prop;
private _set;
private _markCrossTabFeatureFlagSnapshot;
private _remove;
private _persist;
private _rebuildEventProperties;
/**
* Check if the feature flag cache is stale based on the configured TTL.
*/
private _isCacheStale;
/**
* Triggers a debounced reload when cache staleness is first detected.
* Returns true if cache is stale, false otherwise.
*/
private _checkAndTriggerStaleRefresh;
private _getValidEvaluationEnvironments;
private _getValidFlagKeys;
initialize(): void;
updateFlags(flags: Record<string, boolean | string>, payloads?: Record<string, JsonType>, options?: {
merge?: boolean;
}): void;
get hasLoadedFlags(): boolean;
getFlags(): string[];
getFlagsWithDetails(): Record<string, FeatureFlagDetail>;
getAllFeatureFlags(): FeatureFlagResult[];
getFlagVariants(): Record<string, string | boolean>;
getFlagPayloads(): Record<string, JsonType>;
/**
* Reloads feature flags asynchronously.
*
* Constraints:
*
* 1. Avoid parallel requests
* 2. Delay a few milliseconds after each reloadFeatureFlags call to batch subsequent changes together
*/
reloadFeatureFlags(): void;
private _clearDebouncer;
onReloading(handler: () => void): () => void;
ensureFlagsLoaded(): void;
setAnonymousDistinctId(anon_distinct_id: string): void;
setReloadingPaused(isPaused: boolean): void;
resetFlagCallReported(): void;
_callFlagsEndpoint(options?: {
disableFlags?: boolean;
}): void;
private _hasStatusZeroCircuitBreakerTripped;
private _trackStatusZeroReachability;
/**
* Get feature flag's value for user.
*
* By default, this method may return cached values from localStorage if the `/flags` endpoint
* hasn't responded yet. This reduces flicker but means you might briefly see stale values
* (e.g., a flag that was disabled on the server).
*
* ### Usage:
*
* if(posthog.getFeatureFlag('my-flag') === 'some-variant') { // do something }
*
* // Only use fresh values from the server (returns undefined until /flags responds)
* if(posthog.getFeatureFlag('my-flag', { fresh: true }) === 'some-variant') { // do something }
*
* @param {String} key Key of the feature flag.
* @param {Object} options Optional settings.
* @param {boolean} [options.send_event=true] If false, won't send a $feature_flag_called event to PostHog.
* @param {boolean} [options.fresh=false] If true, only returns values loaded from the server, not cached localStorage values.
* Use this when you need to ensure the flag value reflects the current server state,
* such as after disabling a flag. Returns undefined until the /flags endpoint responds.
* @returns {boolean | string | undefined} The flag value, or undefined if not found or not yet loaded.
*/
getFeatureFlag(key: string, options?: FeatureFlagOptions): boolean | string | undefined;
getFeatureFlagDetails(key: string): FeatureFlagDetail | undefined;
/**
* @deprecated Use `getFeatureFlagResult()` instead which properly tracks the feature flag call.
* `getFeatureFlagPayload()` does not emit the `$feature_flag_called` event which may result in
* missing analytics. This method will be removed in a future version.
*/
getFeatureFlagPayload(key: string): JsonType;
/**
* Get a feature flag result including both the flag value and payload, while properly tracking the call.
* This method emits the `$feature_flag_called` event by default.
*
* By default, this method may return cached values from localStorage if the `/flags` endpoint
* hasn't responded yet. This reduces flicker but means you might briefly see stale values
* (e.g., a flag that was disabled on the server).
*
* ### Usage:
*
* const result = posthog.getFeatureFlagResult('my-flag')
* if (result?.enabled) {
* console.log('Flag is enabled with payload:', result.payload)
* }
*
* // Only use fresh values from the server
* const freshResult = posthog.getFeatureFlagResult('my-flag', { fresh: true })
*
* @param {String} key Key of the feature flag.
* @param {Object} [options] Options for the feature flag lookup.
* @param {boolean} [options.send_event=true] If false, won't send the $feature_flag_called event.
* @param {boolean} [options.fresh=false] If true, only returns values loaded from the server, not cached localStorage values.
* Use this when you need to ensure the flag value reflects the current server state.
* Returns undefined until the /flags endpoint responds.
* @returns {FeatureFlagResult | undefined} The feature flag result including key, enabled, variant, and payload.
*/
getFeatureFlagResult(key: string, options?: FeatureFlagOptions): FeatureFlagResult | undefined;
private _captureFeatureFlagCalled;
getRemoteConfigPayload(key: string, callback: RemoteConfigFeatureFlagCallback): void;
private _getRemoteConfigPayload;
/**
* See if feature flag is enabled for user.
*
* By default, this method may return cached values from localStorage if the `/flags` endpoint
* hasn't responded yet. This reduces flicker but means you might briefly see stale values
* (e.g., a flag that was disabled on the server).
*
* ### Usage:
*
* if(posthog.isFeatureEnabled('beta-feature')) { // do something }
*
* // Only use fresh values from the server
* if(posthog.isFeatureEnabled('beta-feature', { fresh: true })) { // do something }
*
* @param {String} key Key of the feature flag.
* @param {Object} [options] Optional settings.
* @param {boolean} [options.send_event=true] If false, won't send a $feature_flag_called event to PostHog.
* @param {boolean} [options.fresh=false] If true, only returns values loaded from the server, not cached localStorage values.
* Use this when you need to ensure the flag value reflects the current server state.
* Returns undefined until the /flags endpoint responds.
* @param {boolean} [options.defaultValue] Value to return when the flag has no value, e.g. flags have not loaded yet or no flag with that key exists.
* @returns {boolean | undefined} Whether the flag is enabled; when the flag has no value, defaultValue if given, otherwise undefined.
*/
isFeatureEnabled(key: string, options: IsFeatureEnabledOptions & {
defaultValue: boolean;
}): boolean;
isFeatureEnabled(key: string, options?: IsFeatureEnabledOptions): boolean | undefined;
addFeatureFlagsHandler(handler: FeatureFlagsCallback): void;
removeFeatureFlagsHandler(handler: FeatureFlagsCallback): void;
receivedFeatureFlags(response: Partial<FlagsResponse>, errorsLoading?: boolean, options?: {
partialResponse?: boolean;
}): void;
private _receivedFeatureFlags;
/**
* @deprecated Use overrideFeatureFlags instead. This will be removed in a future version.
*/
override(flags: boolean | string[] | Record<string, string | boolean>, suppressWarning?: boolean): void;
/**
* Override feature flags on the client-side. Useful for setting non-persistent feature flags,
* or for testing/debugging feature flags in the PostHog app.
*
* ### Usage:
*
* - posthog.featureFlags.overrideFeatureFlags(false) // clear all overrides
* - posthog.featureFlags.overrideFeatureFlags(['beta-feature']) // enable flags
* - posthog.featureFlags.overrideFeatureFlags({'beta-feature': 'variant'}) // set variants
* - posthog.featureFlags.overrideFeatureFlags({ flags: ['beta-feature'] }) // enable flags
* - posthog.featureFlags.overrideFeatureFlags({ flags: {'beta-feature': 'variant'} }) // set variants
* - posthog.featureFlags.overrideFeatureFlags({ // set both flags and payloads
* flags: {'beta-feature': 'variant'},
* payloads: { 'beta-feature': { someData: true } }
* })
* - posthog.featureFlags.overrideFeatureFlags({ // only override payloads
* payloads: { 'beta-feature': { someData: true } }
* })
*/
overrideFeatureFlags(overrideOptions: OverrideFeatureFlagsOptions): void;
private _overrideFeatureFlags;
onFeatureFlags(callback: FeatureFlagsCallback): () => void;
updateEarlyAccessFeatureEnrollment(key: string, isEnrolled: boolean, stage?: string): void;
getEarlyAccessFeatures(callback: EarlyAccessFeatureCallback, force_reload?: boolean, stages?: EarlyAccessFeatureStage[]): void;
private _getEarlyAccessFeatures;
_prepareFeatureFlagsForCallbacks(): {
flags: string[];
flagVariants: Record<string, string | boolean>;
};
_fireFeatureFlagsCallbacks(errorsLoading?: boolean): void;
/**
* Set override person properties for feature flags.
* This is used when dealing with new persons / where you don't want to wait for ingestion
* to update user properties.
*/
setPersonPropertiesForFlags(properties: Properties, reloadFeatureFlags?: boolean): void;
private _setPersonPropertiesForFlags;
/**
* Remove override person properties used for feature flags.
* This is the counterpart to setPersonPropertiesForFlags, used when person properties
* are unset so flags re-evaluate without the removed values.
*/
unsetPersonPropertiesForFlags(propertyNames: string[], reloadFeatureFlags?: boolean): void;
resetPersonPropertiesForFlags(reloadFeatureFlags?: boolean): void;
/**
* Set override group properties for feature flags.
* This is used when dealing with new groups / where you don't want to wait for ingestion
* to update properties.
* Takes in an object, the key of which is the group type.
* For example:
* setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } })
*/
setGroupPropertiesForFlags(properties: {
[type: string]: Properties;
}, reloadFeatureFlags?: boolean): void;
resetGroupPropertiesForFlags(group_type?: string): void;
reset(): void;
}
declare class PostHogLogs implements Extension$1 {
private readonly _instance;
readonly name: _posthog_browser_common.ExtensionToken<PostHogLogs>;
private _isLogsEnabled;
private _isLoaded;
private _isLoading;
private readonly _logger;
private readonly _coreLogger;
private _queue;
private _core;
private _resolvedConfig;
private _resolvedFrom;
private _capture_logger;
private _consoleQueue;
private _consoleCore;
private _consoleLogsDispose;
private _consoleResolvedConfig;
private _consoleResolvedFrom;
private _consecutiveStatusZeroFailures;
private _client?;
private _remoteConfigSubscription?;
private _disposed;
private _consoleBuffer;
private _consoleRecorderUnpatchers;
private _isRecordingConsole;
private _consoleRecorderTimeout;
private _isRecordingConsoleEntry;
constructor(_instance: PostHog);
private _onReconnect;
private _buildCore;
private _getCore;
private _getConsoleCore;
setup(client: Client): void;
dispose(): void;
onRemoteConfig(result: DeepReadonly<RemoteConfigResult>): void;
reset(): void;
captureLog(options: CaptureLogOptions): void;
/** @internal */
captureConsoleLog(options: CaptureLogOptions): void;
/** @internal */
captureBufferedConsoleLog(options: CaptureLogOptions, context: LogSdkContext, occurredAtMs: number): void;
private _persistedCaptureHint;
private _remoteConfigWillArrive;
/**
* Releases everything console capture is holding when capturing is turned off: the
* pre-load buffer, the `console` patches, and console records already queued — at
* that moment rather than whenever the page next writes to the console.
*
* @internal
*/
_onOptOut(): void;
private _stopRecorderStartedByPersistedHint;
private _startConsoleRecorder;
private _recordConsoleEntry;
private _stopConsoleRecorder;
private _takeConsoleBuffer;
get logger(): Logger;
flushLogs(transport?: 'XHR' | 'fetch' | 'sendBeacon'): void;
private _logFlushError;
loadIfEnabled(): void;
private _createHost;
private _sendLogsBatch;
private _trackEndpointReachability;
private _flushViaTransport;
private _drainQueueViaTransport;
private _logsUrl;
private _getSdkContext;
}
/**
* The `posthog.metrics` extension: a statsd-style pre-aggregating client.
*
* ```ts
* posthog.metrics.count('orders_created', 1)
* posthog.metrics.gauge('active_connections', 42)
* posthog.metrics.histogram('api_latency', 187, { unit: 'ms' })
* ```
*
* Aggregation, series identity, and flush policy live in core's
* `PostHogMetrics`; this wrapper adapts it to the browser request layer.
*/
declare class PostHogMetrics implements Extension {
private readonly _instance;
private readonly _logger;
private _core;
private _resolvedFrom;
constructor(_instance: PostHog);
initialize(): void;
private _getCore;
/** Add to a counter — things that only go up. Value defaults to 1. */
count(name: string, value?: number, options?: CaptureMetricOptions): void;
/** Record the current value of something that goes up and down. */
gauge(name: string, value: number, options?: CaptureMetricOptions): void;
/** Record one observation of a distribution (latency, payload size). */
histogram(name: string, value: number, options?: CaptureMetricOptions): void;
/**
* Sends the aggregated window now. With a transport, the window is
* drained synchronously — bypassing the flush serializer, which could be
* awaiting an in-flight send that will never finish during unload — and
* the payload is handed to that transport in the same tick, so the
* pagehide `sendBeacon` drain survives the page going away. A drained
* window is not retried; the page is gone either way.
*/
flush(transport?: 'XHR' | 'fetch' | 'sendBeacon'): Promise<void>;
reset(): void;
private _createHost;
private _sendMetricsBatch;
private _metricsUrl;
}
type PostHogInterface = Omit<PostHog$1, 'config' | 'init' | 'set_config'> & {
config: PostHogConfig;
set_config(config: Partial<PostHogConfig>): void;
};
type PostHogConfig = Omit<PostHogConfig$1, 'loaded'> & {
loaded: (posthog: PostHogInterface) => void;
/**
* Disables capturing the `$device_model` super-property.
*
* When capturing is enabled (the default), PostHog resolves the hardware model once during init
* via `navigator.userAgentData.getHighEntropyValues(['model'])` and registers it as the raw OEM
* code (e.g. `Pixel 7`). This is Chromium-only and only meaningful on Android — it resolves to
* `undefined` on Safari/Firefox and to an empty string on desktop, in which cases nothing is
* registered.
*
* This opt-out is offered because `getHighEntropyValues` is still experimental and Chromium-only
* (not yet a cross-browser standard); set it to `true` to skip the call entirely.
*
* @default false
*/
disableDeviceModel?: boolean;
/**
* Internal: Extension class overrides for tree-shaking support.
* When provided, these classes are used instead of the default imports.
* This enables entrypoints to control which extensions are bundled.
* @internal
*/
__extensionClasses?: {
exceptions?: ExtensionConstructor<PostHogExceptions>;
historyAutocapture?: ExtensionConstructor<HistoryAutocapture>;
tracingHeaders?: ExtensionConstructor<TracingHeaders>;
siteApps?: ExtensionConstructor<SiteApps>;
sessionRecording?: ExtensionConstructor<SessionRecording>;
autocapture?: ExtensionConstructor<Autocapture>;
productTours?: ExtensionConstructor<PostHogProductTours>;
heatmaps?: ExtensionConstructor<Heatmaps>;
webVitalsAutocapture?: ExtensionConstructor<WebVitalsAutocapture>;
exceptionObserver?: ExtensionConstructor<ExceptionObserver>;
deadClicksAutocapture?: ExtensionConstructor<DeadClicksAutocapture>;
surveys?: ExtensionConstructor<BrowserSurveys>;
toolbar?: ExtensionConstructor<Toolbar>;
experiments?: ExtensionConstructor<WebExperiments>;
conversations?: ExtensionConstructor<PostHogConversations>;
featureFlags?: ExtensionConstructor<PostHogFeatureFlags>;
logs?: ExtensionConstructor<PostHogLogs>;
metrics?: ExtensionConstructor<PostHogMetrics>;
};
};
type NextOptions = {
revalidate: false | 0 | number;
tags: string[];
};
interface RequestWithOptions {
url: string;
data?: Record<string, any> | Record<string, any>[];
headers?: Record<string, any>;
transport?: 'XHR' | 'fetch' | 'sendBeacon';
method?: 'POST' | 'GET';
urlQueryArgs?: {
compression: Compression;
};
callback?: (response: RequestResponse) => void;
timeout?: number;
noRetries?: boolean;
disableTransport?: ('XHR' | 'fetch' | 'sendBeacon')[];
compression?: Compression | 'best-available';
/** Used when best-available compression negotiation does not select a format. */
compressionFallback?: Compression;
/**
* Controls where the request dispatch time is sent.
* - `body` adds ISO `sent_at` to the request object, or every object in an array (for example, flags and recordings).
* - `capture-body` wraps events in `{ api_key, batch, sent_at }` with an ISO timestamp.
* - `query` adds numeric `sent_at` to POST requests or cache-busting `_` to GET requests.
*/
timestampMode?: 'body' | 'capture-body' | 'query';
fetchOptions?: {
cache?: RequestInit['cache'];
next?: NextOptions;
};
/**
* When set, `_send_request` invokes `callback` with a synthetic response
* on the paths that otherwise drop a request without notifying the caller
* (client not loaded, server rate limit). Opt-in so existing callers keep
* their current behavior; the logs pipeline uses it to keep records for a
* later retry instead of losing them silently.
*/
fireCallbackOnDrop?: boolean;
}
interface QueuedRequestWithOptions extends RequestWithOptions {
/** key of queue, e.g. 'sessionRecording' vs 'event' */
batchKey?: string;
}
interface RetriableRequestWithOptions extends QueuedRequestWithOptions {
retriesPerformedSoFar?: number;
}
/** the config stored in persistence when session recording remote config is received */
type SessionRecordingPersistedConfig = Omit<SessionRecordingRemoteConfig, 'recordCanvas' | 'canvasFps' | 'canvasQuality' | 'networkPayloadCapture' | 'sampleRate' | 'minimumDurationMilliseconds'> & {
/**
* Used to determine if the persisted config is still valid or we need to wait for a new one
* only accepts undefined since older versions of the library didn't set this.
*/
cache_timestamp?: number;
enabled: boolean;
networkPayloadCapture: SessionRecordingRemoteConfig['networkPayloadCapture'] & {
capturePerformance: RemoteConfig['capturePerformance'];
};
canvasRecording: {
enabled: SessionRecordingRemoteConfig['recordCanvas'];
fps: SessionRecordingRemoteConfig['canvasFps'];
quality: SessionRecordingRemoteConfig['canvasQuality'];
};
sampleRate: number | null;
minimumDurationMilliseconds: number | null | undefined;
};
/**
* Outcome of a remote config fetch: the config, or an explicit failure.
* @internal
*/
type RemoteConfigResult = RemoteConfigResult$1;
/**
* Flags returns feature flags and their payloads
*/
interface FlagsResponse extends RemoteConfig {
featureFlags: Record<string, string | boolean>;
featureFlagPayloads: Record<string, JsonType>;
errorsWhileComputingFlags: boolean;
requestId?: string;
flags: Record<string, FeatureFlagDetail>;
evaluatedAt?: number;
/**
* Server-controlled gate for minimal `$feature_flag_called` events. `true` only when the
* project opted in; omitted otherwise. Absence always means full events.
*/
minimalFlagCalledEvents?: boolean;
}
type SiteAppGlobals = {
event: {
uuid: string;
event: EventName;
properties: Properties;
timestamp?: Date;
elements_chain?: string;
distinct_id?: string;
};
person: {
properties: Properties;
};
groups: Record<string, {
id: string;
type: string;
properties: Properties;
}>;
};
type SiteAppLoader = {
id: string;
init: (config: {
posthog: PostHog;
callback: (success: boolean) => void;
}) => {
processEvent?: (globals: SiteAppGlobals) => void;
};
};
type SiteApp = {
id: string;
loaded: boolean;
errored: boolean;
processedBuffer: boolean;
processEvent?: (globals: SiteAppGlobals) => void;
};
interface PersistentStore {
_is_supported: () => boolean;
_error: (error: any) => void;
_parse: (name: string) => any;
_get: (name: string) => any;
_set: (name: string, value: any, expire_days?: number | null, cross_subdomain?: boolean, secure?: boolean, debug?: boolean) => boolean;
_remove: (name: string, cross_subdomain?: boolean) => void;
}
type EventHandler = (event: Event) => boolean | void;
type SnippetArrayItem = [method: string, ...args: any[]];
type ErrorEventArgs = [
event: string | Event,
source?: string | undefined,
lineno?: number | undefined,
colno?: number | undefined,
error?: Error | undefined
];
declare const severityLevels: readonly ["fatal", "error", "warning", "log", "info", "debug"];
type SessionStartReason = 'sampling_overridden' | 'recording_initialized' | 'linked_flag_matched' | 'linked_flag_overridden' | typeof SAMPLED | 'session_id_changed' | 'url_trigger_matched' | 'event_trigger_matched';
type OverrideConfig = {
sampling: boolean;
linked_flag: boolean;
url_trigger: boolean;
event_trigger: boolean;
};
/**
* Integrate Sentry with PostHog. This will add a direct link to the person in Sentry, and an $exception event in PostHog
*
* ### Usage
*
* Sentry.init({
* dsn: 'https://example',
* integrations: [
* new posthog.SentryIntegration(posthog)
* ]
* })
*
* @param {Object} [posthog] The posthog object
* @param {string} [organization] Optional: The Sentry organization, used to send a direct link from PostHog to Sentry
* @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry
* @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)
* @param {SeverityLevel[] | '*'} [severityAllowList] Optional: send events matching the provided levels. Use '*' to send all events (default: ['error'])
* @param {boolean} [sendExceptionsToPostHog] Optional: capture exceptions as events in PostHog (default: true)
*/
type _SentryEvent = any;
type _SentryEventProcessor = any;
type _SentryHub = any;
interface _SentryIntegration {
name: string;
processEvent(event: _SentryEvent): _SentryEvent;
}
interface _SentryIntegrationClass {
name: string;
setupOnce(addGlobalEventProcessor: (callback: _SentryEventProcessor) => void, getCurrentHub: () => _SentryHub): void;
}
type SentryIntegrationOptions = {
organization?: string;
projectId?: number;
prefix?: string;
severityAllowList?: SeverityLevel[] | '*';
sendExceptionsToPostHog?: boolean;
};
declare function sentryIntegration(_posthog: PostHog, options?: SentryIntegrationOptions): _SentryIntegration;
declare class SentryIntegration implements _SentryIntegrationClass {
name: string;
setupOnce: (addGlobalEventProcessor: (callback: _SentryEventProcessor) => void, getCurrentHub: () => _SentryHub) => void;
constructor(_posthog: PostHog, organization?: string, projectId?: number, prefix?: string, severityAllowList?: SeverityLevel[] | '*', sendExceptionsToPostHog?: boolean);
}
interface PageViewEventProperties {
$pageview_id?: string;
$prev_pageview_id?: string;
$prev_pageview_pathname?: string;
$prev_pageview_duration?: number;
$prev_pageview_last_scroll?: number;
$prev_pageview_last_scroll_percentage?: number;
$prev_pageview_max_scroll?: number;
$prev_pageview_max_scroll_percentage?: number;
$prev_pageview_last_content?: number;
$prev_pageview_last_content_percentage?: number;
$prev_pageview_max_content?: number;
$prev_pageview_max_content_percentage?: number;
}
declare class PageViewManager {
_currentPageview?: {
timestamp: Date;
pageViewId: string | undefined;
pathname: string | undefined;
};
_instance: PostHog;
private _unsubscribeSessionId?;
constructor(instance: PostHog);
private _setupSessionRotationHandler;
private _onSessionIdChange;
destroy(): void;
doPageView(timestamp: Date, pageViewId?: string): PageViewEventProperties;
doPageLeave(timestamp: Date): PageViewEventProperties;
doEvent(): PageViewEventProperties;
private _previousPageViewProperties;
}
/**
* PostHog Persistence Object
* @constructor
*/
declare class PostHogPersistence {
private _config;
props: Properties;
private _storage;
private _campaign_params_url;
private readonly _name;
_disabled: boolean | undefined;
private _secure;
private _expire_days;
private _default_expiry;
private _cross_subdomain;
private _slotState;
private _splitStorageEligible;
private _splitStorage;
private readonly _ownsSplitStorage;
private _pendingSaveTimer;
private _lastSeenCookiePropertiesFingerprint;
private _lastSeenMainCookieValue;
private _cookieIdentityChangePending;
private _cookieSyncSuppressed;
private _pendingCrossTabFeatureFlagChanges;
private _storageMigrationInProgress;
private _localIdentityChangePending;
private _crossTabFeatureFlagIdentityMismatch;
private readonly _crossTabFeatureFlagHandlers;
private _onStorage?;
/**
* @param {PostHogConfig} config initial PostHog configuration
* @param {boolean=} isDisabled should persistence be disabled (e.g. because of consent management)
*/
constructor(config: PostHogConfig, isDisabled?: boolean, ownsSplitStorage?: boolean);
markCrossTabFeatureFlagChanges(changes: Record<string, readonly string[] | true>): void;
onCrossTabFeatureFlagChange(handler: () => void): () => void;
destroy(): void;
private _syncCrossTabFeatureFlagProperties;
private _hasCrossTabFeatureFlagIdentityMismatch;
private _rememberCrossTabStorageFingerprint;
private _mergeCrossTabFeatureFlagProperties;
private _reconcileCrossTabFeatureFlagPropertiesBeforeWrite;
private _setCrossTabFeatureFlagChangesPending;
private _markAllCrossTabFeatureFlagChangesPending;
private _markLoadedCrossTabFeatureFlagChangesPending;
private _mergePendingCrossTabFeatureFlagChanges;
private _markPendingCrossTabFeatureFlagChanges;
private _saveDebounceMs;
private _rememberCurrentCookieProperties;
/**
* Adopt shared-cookie changes made by a sibling subdomain without replacing
* localStorage-only or pending in-memory properties. Returns true when a new
* non-empty cookie snapshot was observed.
*/
syncCookieProperties(): boolean;
private _syncCookieProperties;
consumeCookieIdentityChange(): boolean;
_beginCookieSyncSuppression(ignoreDisabled?: boolean): boolean;
_publishSuppressedCookieSnapshot(): void;
_endCookieSyncSuppression(publish?: boolean): void;
/**
* Returns whether persistence is disabled. Only available in SDKs > 1.257.1. Do not use on extensions, otherwise
* it'll break backwards compatibility for any version before 1.257.1.
*/
isDisabled?(): boolean;
private _buildStorage;
private _groupEntryName;
private _resolveSplitStorage;
properties(): Properties;
/**
* Reload persisted properties from storage.
*
* @param allowDisabled - Read while this instance is disabled when shared consent changed in another tab
* and the in-memory disabled state has not yet been reconciled.
*/
load(allowDisabled?: boolean): void;
private _loadGroupEntries;
private _mainCarriesGroupKey;
private _groupEntryIsStale;
/**
* Refresh a single key from on-disk storage into `this.props` without
* touching the rest. Used by `SessionIdManager` on the cross-tab idle
* path so we can pick up a sibling tab's SESSION_ID write without
* either:
* - flushing our own (potentially stale) whole-props blob to storage
* via `flush()`, which would clobber the sibling's write, or
* - replacing all of `props` via `load()`, which would discard any
* in-memory writes that haven't yet been debounced to storage.
*/
refreshKey(prop: string): void;
/**
* NOTE: Saving frequently causes issues with Recordings and Consent Management Platform (CMP) tools which
* observe cookie changes, and modify their UI, often causing infinite loops.
* As such callers of this should ideally check that the data has changed beforehand
*/
save(): void;
/**
* Force any pending debounced save to land in storage immediately.
* No-op when there is no pending timer — crucially, this means the
* `beforeunload` / `pagehide` listeners installed in the constructor
* cannot accidentally resurrect a storage entry that `remove()` or
* `clear()` just deleted. Without this guard, the listener would
* call `_writeNow()` and write the in-memory `props` (now `{}`) back
* to storage, breaking `posthog.reset()` / opt-out flows.
*/
flush(): void;
private _writeNow;
private _writeNowSplit;
private _partitionProps;
private _entryFingerprint;
private _writeEntry;
remove({ keepGroupEntries }?: {
keepGroupEntries?: boolean;
}): void;
clear(): void;
/**
* @param {Object} props
* @param {*=} default_value
* @param {number=} days
*/
register_once(props: Properties, default_value: any, days?: number): boolean;
/**
* @param {Object} props
* @param {number=} days
*/
register(props: Properties, days?: number): boolean;
unregister(propOrProps: string | readonly string[]): void;
update_campaign_params(): void;
update_search_keyword(): void;
update_referrer_info(): void;
set_initial_person_info(): void;
get_initial_props(): Properties;
safe_merge(props: Properties): Properties;
update_config(config: PostHogConfig, oldConfig: PostHogConfig, isDisabled?: boolean): void;
set_disabled(disabled: boolean): void;
set_cross_subdomain(cross_subdomain: boolean): void;
set_secure(secure: boolean): void;
set_event_timer(event_name: string, timestamp: number): void;
remove_event_timer(event_name: string): number;
get_property(prop: string): any;
set_property(prop: string, to: any): void;
private _setProp;
private _deleteProp;
private _markGroupDirty;
private _slotWriteState;
}
declare class RateLimiter {
instance: PostHog;
serverLimits: Record<string, number>;
lastEventRateLimited: boolean;
constructor(instance: PostHog);
get captureEventsPerSecond(): number;
get captureEventsBurstLimit(): number;
clientRateLimitContext(checkOnly?: boolean): {
isRateLimited: boolean;
remainingTokens: number;
};
private _isPropertyAllowed;
/**
* The page the limiter tripped on, without the query string or hash - enough to spot a
* self-reloading 404 without putting whatever a customer keeps in their query params into
* an ingestion warning. Because this value recombines `$current_url` and `$pathname`, omit it
* if either standard property has been denylisted rather than reintroducing denied context.
*/
private _triggeringPage;
private _captureWarning;
isServerRateLimited(batchKey: string | undefined): boolean;
checkForLimiting: (httpResponse: RequestResponse) => void;
}
declare class RemoteConfigLoader {
private readonly _instance;
constructor(_instance: PostHog);
get remoteConfig(): RemoteConfig | undefined;
private _loadRemoteConfigJs;
private _loadRemoteConfigJSON;
load(): void;
private _onRemoteConfig;
}
declare class RequestQueue {
private _isPaused;
private _queue;
private _flushTimeout?;
private _flushTimeoutMs;
private _sendRequest;
constructor(sendRequest: (req: QueuedRequestWithOptions) => void, config?: RequestQueueConfig);
enqueue(req: QueuedRequestWithOptions): void;
unload(): void;
enable(): void;
private _setFlushTimeout;
private _sendRequestSafely;
private _clearFlushTimeout;
private _formatQueue;
}
declare class RetryQueue {
private _instance;
private _isPolling;
private _poller;
private _pollIntervalMs;
private _queue;
private _areWeOnline;
private _onlineListener;
private _offlineListener;
constructor(_instance: PostHog);
get length(): number;
retriableRequest({ retriesPerformedSoFar, ...options }: RetriableRequestWithOptions): void;
private _enqueue;
private _poll;
private _flush;
unload(): void;
}
interface ScrollContext {
maxScrollHeight?: number;
maxScrollY?: number;
lastScrollY?: number;
maxContentHeight?: number;
maxContentY?: number;
lastContentY?: number;
}
declare class ScrollManager {
private _instance;
private _context;
constructor(_instance: PostHog);
private get _scrollRoot();
getContext(): ScrollContext | undefined;
resetContext(): ScrollContext | undefined;
private _updateScrollData;
startMeasuringScrollPosition(): void;
scrollElement(): Element | undefined;
private _scrollPosition;
scrollY(): number;
scrollX(): number;
}
interface LegacySessionSourceProps {
initialPathName: string;
referringDomain: string;
utm_medium?: string;
utm_source?: string;
utm_campaign?: string;
utm_content?: string;
utm_term?: string;
}
interface CurrentSessionSourceProps {
r: string;
u: string | undefined;
}
interface StoredSessionSourceProps {
sessionId: string;
props: LegacySessionSourceProps | CurrentSessionSourceProps;
}
declare class SessionPropsManager {
private readonly _instance;
private readonly _sessionIdManager;
private readonly _persistence;
private readonly _sessionSourceParamGenerator;
constructor(instance: PostHog, sessionIdManager: SessionIdManager, persistence: PostHogPersistence, sessionSourceParamGenerator?: (instance?: PostHog) => LegacySessionSourceProps | CurrentSessionSourceProps);
_getStored(): StoredSessionSourceProps | undefined;
_onSessionIdCallback: (sessionId: string) => void;
getSetOnceProps(): Record<string, any>;
getSessionProps(): Record<string, any>;
}
/**
* The request router helps simplify the logic to determine which endpoints should be called for which things
* The basic idea is that for a given region (US or EU), we have a set of endpoints that we should call depending
* on the type of request (events, replays, flags, etc.) and handle overrides that may come from configs or the flags endpoint
*/
declare const RequestRouterRegion: {
readonly US: "us";
readonly EU: "eu";
readonly CUSTOM: "custom";
};
type RequestRouterRegion = (typeof RequestRouterRegion)[keyof typeof RequestRouterRegion];
type RequestRouterTarget = 'api' | 'ui' | 'assets' | 'flags';
declare class RequestRouter {
instance: PostHog;
private _regionCache;
private _ingestionEndpoints?;
constructor(instance: PostHog);
get apiHost(): string;
get flagsApiHost(): string;
get uiHost(): string | undefined;
get region(): RequestRouterRegion;
private _staticAssetHostOverride;
private _urlKey;
private _prepareEndpoint;
isIngestionEndpoint(url: string): boolean;
endpointFor(target: RequestRouterTarget, path?: string): string;
}
declare class ExternalIntegrations {
private readonly _instance;
constructor(_instance: PostHog);
private _loadScript;
startIfEnabledOrStop(): void;
}
/** One shared extension client and lifecycle host per browser-v1 PostHog instance. */
declare class BrowserClientAdapter implements Client, Disposable {
readonly instance: PostHog;
readonly kv: KeyValueStore;
readonly onEvent: Listener<CapturedEventInfo>;
readonly onRemoteConfig: Listener<DeepReadonly<RemoteConfigResult>>;
private readonly _logger;
private readonly _runtime;
private _latestRemoteConfigResult;
private _disposed;
constructor(instance: PostHog);
get logger(): Logger$1;
get distinctId(): string;
get anonymousId(): string;
get deviceId(): string | undefined;
get library(): {
name: string;
version: string;
};
get initialPersonProperties(): Record<string, unknown>;
get groups(): Record<string, string>;
get session(): SessionContext$1;
get canCapture(): boolean;
get projectToken(): string;
add(extension: Extension$1): Promise<void>;
getExtension<T extends Extension$1>(token: ExtensionToken<T>): T | undefined;
getExtension<T extends Extension$1 = Extension$1>(name: string): T | undefined;
capture(event: string, properties?: Properties | null, options?: CaptureOptions): Promise<void>;
registerDynamicEventProperties(producer: () => Record<string, unknown>): Disposable;
handleRemoteConfig(result: RemoteConfigResult): void;
sendRequest(path: string, init?: SendRequestInit): Promise<ApiResponse>;
dispose(): void;
}
/** Browser-v1 compatibility wrapper for the SDK-neutral autocapture extension. */
declare class BrowserAutocapture extends Autocapture {
instance: PostHog;
constructor(instance: PostHog);
}
type OnlyValidKeys<T, Shape> = T extends Shape ? (Exclude<keyof T, keyof Shape> extends never ? T : never) : never;
declare class DeprecatedWebPerformanceObserver {
get _forceAllowLocalhost(): boolean;
set _forceAllowLocalhost(value: boolean);
private __forceAllowLocalhost;
}
/**
*
* This is the SDK reference for the PostHog JavaScript Web SDK.
* You can learn more about example usage in the
* [JavaScript Web SDK documentation](/docs/libraries/js).
* You can also follow [framework specific guides](/docs/frameworks)
* to integrate PostHog into your project.
*
* This SDK is designed for browser environments.
* Use the PostHog [Node.js SDK](/docs/libraries/node) for server-side usage.
*
* @constructor
*/
declare class PostHog implements PostHogInterface {
static __defaultExtensionClasses: PostHogConfig['__extensionClasses'];
__loaded: boolean;
config: PostHogConfig;
_originalUserConfig?: Partial<PostHogConfig>;
rateLimiter: RateLimiter;
scrollManager: ScrollManager;
pageViewManager: PageViewManager;
featureFlags: TreeShakeable<PostHogFeatureFlags>;
surveys: TreeShakeable<BrowserSurveys>;
conversations: TreeShakeable<PostHogConversations>;
logs: TreeShakeable<PostHogLogs>;
metrics: TreeShakeable<PostHogMetrics>;
experiments: TreeShakeable<WebExperiments>;
toolbar: TreeShakeable<Toolbar>;
exceptions: TreeShakeable<PostHogExceptions>;
consent: ConsentManager;
persistence?: PostHogPersistence;
sessionPersistence?: PostHogPersistence;
sessionManager?: SessionIdManager;
sessionPropsManager?: SessionPropsManager;
requestRouter: RequestRouter;
siteApps?: SiteApps;
autocapture?: BrowserAutocapture;
heatmaps?: Heatmaps;
tracingHeaders?: TracingHeaders;
webVitalsAutocapture?: WebVitalsAutocapture;
exceptionObserver?: ExceptionObserver;
deadClicksAutocapture?: DeadClicksAutocapture;
historyAutocapture?: HistoryAutocapture;
productTours?: PostHogProductTours;
_requestQueue?: RequestQueue;
_retryQueue?: RetryQueue;
sessionRecording?: SessionRecording;
externalIntegrations?: ExternalIntegrations;
webPerformance: DeprecatedWebPerformanceObserver;
_initialPageviewCaptured: boolean;
_visibilityStateListener: (() => void) | null;
_personProcessingSetOncePropertiesSent: boolean;
_triggered_notifs: any;
compression?: Compression;
__request_queue: QueuedRequestWithOptions[];
_pendingRemoteConfig?: RemoteConfigResult;
_lastRemoteConfig?: RemoteConfigResult;
_remoteConfigLoader?: RemoteConfigLoader;
analyticsDefaultEndpoint: string;
version: string;
_initialPersonProfilesConfig: 'always' | 'never' | 'identified_only' | null;
_sessionRegisteredPropKeys: Set<string>;
_sessionRegisteredPropertiesStorageKey: string;
_cachedPersonProperties: string | null;
SentryIntegration: typeof SentryIntegration;
sentryIntegration: (options?: SentryIntegrationOptions) => ReturnType<typeof sentryIntegration>;
_internalEventEmitter: SimpleEventEmitter;
private readonly _extensions;
private readonly _extensionEventPropertyProducers;
private _browserClientAdapter;
private _featureFlagsReloadingUnsubscribe;
private _hasStableInitialDistinctId;
private _hasWarnedAboutVolatileIdentity;
private _removeExtension;
private _replaceExtension;
private _inCookielessMode;
private _warnIfVolatileIdentityWithoutStableId;
/**
* Replace a stale cookieless sentinel distinct_id with an anonymous device id.
*
* Consent lives in shared cookie/localStorage, but the in-memory distinct_id does not. A tab
* that started in cookieless mode holds the `$posthog_cookieless` sentinel as its distinct_id;
* when consent is flipped to opted-in in another tab, this tab stops being cookieless
* (`_inCookielessMode()` becomes false) while the sentinel remains in memory. If that sentinel
* then escapes into a real event — or into `identify()` as `$anon_distinct_id` — the plugin
* server never hashes it and every affected browser collapses onto a single
* `$posthog_cookieless` person.
*/
private _healCookielessSentinelDistinctId;
/** @deprecated Use `flagsEndpointWasHit` instead. We migrated to using a new feature flag endpoint and the new method is more semantically accurate */
get decideEndpointWasHit(): boolean;
/**
* Whether feature flags have been initialized for this instance.
*
* @remarks
* Despite the name, this is a proxy for processed feature flag values. It may be true for
* bootstrapped flags before a network request completes.
*
* @returns True once the SDK has processed feature flag values.
*/
get flagsEndpointWasHit(): boolean;
/** DEPRECATED: We keep this to support existing usage but now one should just call .setPersonProperties */
people: {
set: (prop: string | Properties, to?: string, callback?: RequestCallback) => void;
set_once: (prop: string | Properties, to?: string, callback?: RequestCallback) => void;
};
/**
* Creates an uninitialized PostHog instance.
*
* @remarks
* Most browser applications should use the default exported singleton and call `posthog.init()`.
* Construct a new instance only when you need to manage a separate SDK instance manually.
*
* @example
* ```js
* const instance = new PostHog()
* instance.init('<ph_project_api_key>', { api_host: 'https://us.i.posthog.com' })
* ```
*/
constructor();
/**
* Initializes a new instance of the PostHog capturing object.
*
* @remarks
* All new instances are added to the main posthog object as sub properties (such as
* `posthog.library_name`) and also returned by this function. [Learn more about configuration options](https://posthog.com/docs/libraries/js/config)
*
* @example
* ```js
* // basic initialization
* posthog.init('<ph_project_api_key>', {
* api_host: '<ph_client_api_host>'
* })
* ```
*
* @example
* ```js
* // multiple instances
* posthog.init('<ph_project_api_key>', {}, 'project1')
* posthog.init('<ph_project_api_key>', {}, 'project2')
* ```
*
* @public
*
* @param token - Your PostHog API token
* @param config - A dictionary of config options to override
* @param name - The name for the new posthog instance that you want created
*
* {@label Initialization}
*
* @returns The newly initialized PostHog instance
*/
init(token: string, config?: OnlyValidKeys<Partial<PostHogConfig>, Partial<PostHogConfig>>, name?: string): PostHog;
_init(token: string, config?: Partial<PostHogConfig>, name?: string): PostHog;
private _isSharedExtension;
private _enrollExtension;
private _enrollFeatureFlags;
private _initExtensions;
private _processInitTaskQueue;
_onRemoteConfig(result: RemoteConfigResult): void;
_loaded(): void;
_start_queue_if_opted_in(): void;
_dom_loaded(): void;
_handle_unload(): void;
_send_request(options: QueuedRequestWithOptions): void;
_send_retriable_request(options: QueuedRequestWithOptions): void;
/**
* _execute_array() deals with processing any posthog function
* calls that were called before the PostHog library were loaded
* (and are thus stored in an array so they can be called later)
*
* Note: we fire off all the posthog function calls && user defined
* functions BEFORE we fire off posthog capturing calls. This is so
* identify/register/set_config calls can properly modify early
* capturing calls.
*
* @param {Array} array
*/
_execute_array(array: SnippetArrayItem[]): void;
/**
* push() keeps the standard async-array-push
* behavior around after the lib is loaded.
* This is only useful for external integrations that
* do not wish to rely on our convenience methods
* (created in the snippet).
*
* @example
* ```js
* posthog.push(['register', { a: 'b' }]);
* ```
*
* @param {SnippetArrayItem} item A `[function_name, ...args]` array to be executed.
*/
push(item: SnippetArrayItem): void;
/**
* Captures an event with optional properties and configuration.
*
* @remarks
* You can capture arbitrary object-like values as events. [Learn about capture best practices](/docs/product-analytics/capture-events)
*
* @example
* ```js
* // basic event capture
* posthog.capture('cta-button-clicked', {
* button_name: 'Get Started',
* page: 'homepage'
* })
* ```
*
* {@label Capture}
*
* @public
*
* @param event_name - The name of the event (e.g., 'Sign Up', 'Button Click', 'Purchase')
* @param properties - Properties to include with the event describing the user or event details
* @param options - Optional configuration for the capture request
*
* @returns The capture result containing event data, or undefined if capture failed
*/
capture(event_name: EventName, properties?: Properties | null, options?: CaptureOptions$1): CaptureResult | undefined;
_addCaptureHook(callback: (eventName: string, eventPayload?: CaptureResult) => void): () => void;
/**
* Returns an installed browser extension by its typed stable name.
*
* @internal
*/
getExtension<T extends Extension$1>(token: ExtensionToken<T>): T | undefined;
/**
* Returns an installed browser extension by its stable name.
*
* @internal
*/
getExtension<T extends Extension$1 = Extension$1>(name: string): T | undefined;
_getBrowserClientAdapter(): BrowserClientAdapter;
_registerExtensionEventProperties(producer: () => Record<string, unknown>): () => void;
private _processCookieIdentityChange;
/**
* This method is used internally to calculate the event properties before sending it to PostHog. It can also be
* used by integrations (e.g. Segment) to enrich events with PostHog properties before sending them to Segment,
* which is required for some PostHog products to work correctly. (e.g. to have a correct $session_id property).
*
* @param {String} eventName The name of the event. This can be anything the user does - 'Button Click', 'Sign Up', '$pageview', etc.
* @param {Object} eventProperties The properties to include with the event.
* @param {Date} [timestamp] The timestamp of the event, e.g. for calculating time on page. If not set, it'll automatically be set to the current time.
* @param {String} [uuid] The uuid of the event, e.g. for storing the $pageview ID.
* @param {Boolean} [readOnly] Set this if you do not intend to actually send the event, and therefore do not want to update internal state e.g. session timeout
*
* @internal
*/
calculateEventProperties(eventName: string, eventProperties: Properties, timestamp?: Date, uuid?: string, readOnly?: boolean): Properties;
/** @deprecated - deprecated in 1.241.0, use `calculateEventProperties` instead */
_calculate_event_properties: (eventName: string, eventProperties: Properties, timestamp?: Date, uuid?: string, readOnly?: boolean) => Properties;
/**
* Add additional set_once properties to the event when creating a person profile. This allows us to create the
* profile with mostly-accurate properties, despite earlier events not setting them. We do this by storing them in
* persistence.
* @param dataSetOnce
* @param markAsSent - if true, marks the properties as sent so they won't be included in future events.
* Set to false for events like $groupidentify where the server doesn't process person props.
* @param forceIncludeInitialProps - if true, include initial person props even if they've already been sent.
* Used for $identify which creates/merges persons and may be processed out of order.
*/
_calculate_set_once_properties(dataSetOnce?: Properties, markAsSent?: boolean, forceIncludeInitialProps?: boolean): Properties | undefined;
/**
* Registers super properties that are included with all events.
*
* @remarks
* Super properties are stored in persistence and automatically added to every event you capture.
* These values will overwrite any existing super properties with the same keys.
*
* @example
* ```js
* // register a single property
* posthog.register({ plan: 'premium' })
* ```
*
* {@label Capture}
*
* @example
* ```js
* // register multiple properties
* posthog.register({
* email: 'user@example.com',
* account_type: 'business',
* signup_date: '2023-01-15'
* })
* ```
*
* @example
* ```js
* // register with custom expiration
* posthog.register({ campaign: 'summer_sale' }, 7) // expires in 7 days
* ```
*
* @public
*
* @param {Object} properties properties to store about the user
* @param {Number} [days] How many days since the user's last visit to store the super properties
*/
register(properties: Properties, days?: number): void;
/**
* Registers super properties only if they haven't been set before.
*
* @remarks
* Unlike `register()`, this method will not overwrite existing super properties.
* Use this for properties that should only be set once, like signup date or initial referrer.
*
* {@label Capture}
*
* @example
* ```js
* // register once-only properties
* posthog.register_once({
* first_login_date: new Date().toISOString(),
* initial_referrer: document.referrer
* })
* ```
*
* @example
* ```js
* // override existing value if it matches default
* posthog.register_once(
* { user_type: 'premium' },
* 'unknown' // overwrite if current value is 'unknown'
* )
* ```
*
* @public
*
* @param {Object} properties An associative array of properties to store about the user
* @param {*} [default_value] Value to override if already set in super properties (ex: 'False') Default: 'None'
* @param {Number} [days] How many days since the users last visit to store the super properties
*/
register_once(properties: Properties, default_value?: Property, days?: number): void;
/**
* Registers super properties for the current session only.
*
* @remarks
* Session super properties are automatically added to all events during the current browser session.
* Unlike regular super properties, these are cleared when the session ends and are stored in sessionStorage.
*
* {@label Capture}
*
* @example
* ```js
* // register session-specific properties
* posthog.register_for_session({
* current_page_type: 'checkout',
* ab_test_variant: 'control'
* })
* ```
*
* @example
* ```js
* // register properties for user flow tracking
* posthog.register_for_session({
* selected_plan: 'pro',
* completed_steps: 3,
* flow_id: 'signup_flow_v2'
* })
* ```
*
* @public
*
* @param {Object} properties An associative array of properties to store about the user
*/
register_for_session(properties: Properties): void;
/**
* Removes a super property from persistent storage.
*
* @remarks
* This will stop the property from being automatically included in future events.
* The property will be permanently removed from the user's profile.
*
* {@label Capture}
*
* @example
* ```js
* // remove a super property
* posthog.unregister('plan_type')
* ```
*
* @public
*
* @param {String} property The name of the super property to remove
*/
unregister(property: string): void;
/**
* Removes a session super property from the current session.
*
* @remarks
* This will stop the property from being automatically included in future events for this session.
* The property is removed from sessionStorage.
*
* {@label Capture}
*
* @example
* ```js
* // remove a session property
* posthog.unregister_for_session('current_flow')
* ```
*
* @public
*
* @param {String} property The name of the session super property to remove
*/
unregister_for_session(property: string): void;
_register_single(prop: string, value: Property): void;
_clearSessionRegisteredProps(): void;
_persistSessionRegisteredPropKeys(): void;
/**
* Gets the value of a feature flag for the current user.
*
* @remarks
* Returns the feature flag value which can be a boolean, string, or undefined.
* Supports multivariate flags that can return custom string values.
*
* {@label Feature flags}
*
* @example
* ```js
* // check boolean flag
* if (posthog.getFeatureFlag('new-feature')) {
* // show new feature
* }
* ```
*
* @example
* ```js
* // check multivariate flag
* const variant = posthog.getFeatureFlag('button-color')
* if (variant === 'red') {
* // show red button
* }
* ```
*
* @public
*
* @param {string} key Key of the feature flag.
* @param {FeatureFlagOptions} [options] Optional lookup settings. If `{ send_event: false }`, we won't send a `$feature_flag_called` event to PostHog. If `{ fresh: true }`, we won't return cached values from localStorage - only values loaded from the server.
* @returns {boolean | string | undefined} The feature flag value, or undefined if the flag is unavailable.
*/
getFeatureFlag(key: string, options?: FeatureFlagOptions): boolean | string | undefined;
/**
* Get feature flag payload value matching key for user (supports multivariate flags).
*
* {@label Feature flags}
*
* @example
* ```js
* const betaFeature = posthog.getFeatureFlagResult('beta-feature')
* if (betaFeature?.variant === 'some-value') {
* const someValue = betaFeature?.payload
* // do something
* }
* ```
*
* @public
*
* @deprecated Use `getFeatureFlagResult()` instead
*
* @param {string} key Key of the feature flag.
* @returns {JsonType} The feature flag payload.
*/
getFeatureFlagPayload(key: string): JsonType;
/**
* Get a feature flag evaluation result including both the flag value and payload.
*
* By default, this method emits the `$feature_flag_called` event.
*
* {@label Feature flags}
*
* @example
* ```js
* const result = posthog.getFeatureFlagResult('my-flag')
* if (result?.enabled) {
* console.log('Flag is enabled with payload:', result.payload)
* }
* ```
*
* @example
* ```js
* // multivariate flag
* const result = posthog.getFeatureFlagResult('button-color')
* if (result?.variant === 'red') {
* showRedButton(result.payload)
* }
* ```
*
* @public
*
* @param {string} key Key of the feature flag.
* @param {Object} [options] Options for the feature flag lookup.
* @param {boolean} [options.send_event=true] If false, won't send the $feature_flag_called event.
* @param {boolean} [options.fresh=false] If true, won't return cached values from localStorage - only values loaded from the server.
* @returns {FeatureFlagResult | undefined} The feature flag result including key, enabled, variant, and payload.
*/
getFeatureFlagResult(key: string, options?: FeatureFlagOptions): FeatureFlagResult | undefined;
/**
* Returns all currently cached feature flags as `FeatureFlagResult`s. This is a synchronous read of
* the flags from the last load (no network request); call `reloadFeatureFlags()` first to refresh.
* Unlike `getFeatureFlag()`, it does not send a `$feature_flag_called` event.
*
* @returns {FeatureFlagResult[]} All loaded flags, or an empty array if none are loaded.
*/
getAllFeatureFlags(): FeatureFlagResult[];
/**
* Checks if a feature flag is enabled for the current user.
*
* @remarks
* Returns true if the flag is enabled, false if disabled, or undefined if not found
* (unless `defaultValue` is given, which is returned instead of undefined).
* This is a convenience method that treats any truthy value as enabled.
*
* {@label Feature flags}
*
* @example
* ```js
* // simple feature flag check
* if (posthog.isFeatureEnabled('new-checkout')) {
* showNewCheckout()
* }
* ```
*
* @example
* ```js
* // disable event tracking
* if (posthog.isFeatureEnabled('feature', { send_event: false })) {
* // flag checked without sending $feature_flag_called event
* }
* ```
*
* @public
*
* @param {string} key Key of the feature flag.
* @param {IsFeatureEnabledOptions} [options] Optional lookup settings. If `{ send_event: false }`, we won't send a `$feature_flag_called` event to PostHog. If `{ fresh: true }`, we won't return cached values from localStorage - only values loaded from the server. If `{ defaultValue: false }`, we return that value instead of undefined when the flag has no value.
* @returns {boolean | undefined} Whether the feature flag is enabled; when the flag has no value, defaultValue if given, otherwise undefined.
*/
isFeatureEnabled(key: string, options: IsFeatureEnabledOptions & {
defaultValue: boolean;
}): boolean;
isFeatureEnabled(key: string, options?: IsFeatureEnabledOptions): boolean | undefined;
/**
* Feature flag values are cached. If something has changed with your user and you'd like to refetch their flag values, call this method.
*
* {@label Feature flags}
*
* @example
* ```js
* posthog.reloadFeatureFlags()
* ```
*
* @public
*/
reloadFeatureFlags(): void;
/**
* Manually update feature flag values without making a network request.
*
* This is useful when you have feature flag values from an external source
* (e.g., server-side evaluation, edge middleware) and want to inject them
* into the client SDK.
*
* {@label Feature flags}
*
* @example
* ```js
* // Replace all flags with server-evaluated values
* posthog.updateFlags({
* 'my-flag': true,
* 'my-experiment': 'variant-a'
* })
*
* // Merge with existing flags (update only specified flags)
* posthog.updateFlags(
* { 'my-flag': true },
* undefined,
* { merge: true }
* )
*
* // With payloads
* posthog.updateFlags(
* { 'my-flag': true },
* { 'my-flag': { some: 'data' } }
* )
* ```
*
* @param flags - An object mapping flag keys to their values (boolean or string variant)
* @param payloads - Optional object mapping flag keys to their JSON payloads
* @param options - Optional settings. Use `{ merge: true }` to merge with existing flags instead of replacing.
* @public
*/
updateFlags(flags: Record<string, boolean | string>, payloads?: Record<string, JsonType>, options?: {
merge?: boolean;
}): void;
/**
* Opt the user in or out of an early access feature. [Learn more in the docs](/docs/feature-flags/early-access-feature-management#option-2-custom-implementation)
*
* {@label Feature flags}
*
* @example
* ```js
* const toggleBeta = (betaKey) => {
* if (activeBetas.some(
* beta => beta.flagKey === betaKey
* )) {
* posthog.updateEarlyAccessFeatureEnrollment(
* betaKey,
* false
* )
* setActiveBetas(
* prevActiveBetas => prevActiveBetas.filter(
* item => item.flagKey !== betaKey
* )
* );
* return
* }
*
* posthog.updateEarlyAccessFeatureEnrollment(
* betaKey,
* true
* )
* setInactiveBetas(
* prevInactiveBetas => prevInactiveBetas.filter(
* item => item.flagKey !== betaKey
* )
* );
* }
*
* const registerInterest = (featureKey) => {
* posthog.updateEarlyAccessFeatureEnrollment(
* featureKey,
* true
* )
* // Update UI to show user has registered
* }
* ```
*
* @public
*
* @param {String} key The key of the feature flag to update.
* @param {Boolean} isEnrolled Whether the user is enrolled in the feature.
* @param {String} [stage] The stage of the feature flag to update.
*/
updateEarlyAccessFeatureEnrollment(key: string, isEnrolled: boolean, stage?: string): void;
/**
* Get the list of early access features. To check enrollment status, use `isFeatureEnabled`. [Learn more in the docs](/docs/feature-flags/early-access-feature-management#option-2-custom-implementation)
*
* {@label Feature flags}
*
* @example
* ```js
* const posthog = usePostHog()
* const activeFlags = useActiveFeatureFlags()
*
* const [activeBetas, setActiveBetas] = useState([])
* const [inactiveBetas, setInactiveBetas] = useState([])
* const [comingSoonFeatures, setComingSoonFeatures] = useState([])
*
* useEffect(() => {
* posthog.getEarlyAccessFeatures((features) => {
* // Filter features by stage
* const betaFeatures = features.filter(feature => feature.stage === 'beta')
* const conceptFeatures = features.filter(feature => feature.stage === 'concept')
*
* setComingSoonFeatures(conceptFeatures)
*
* if (!activeFlags || activeFlags.length === 0) {
* setInactiveBetas(betaFeatures)
* return
* }
*
* const activeBetas = betaFeatures.filter(
* beta => activeFlags.includes(beta.flagKey)
* );
* const inactiveBetas = betaFeatures.filter(
* beta => !activeFlags.includes(beta.flagKey)
* );
* setActiveBetas(activeBetas)
* setInactiveBetas(inactiveBetas)
* }, true, ['concept', 'beta'])
* }, [activeFlags])
* ```
*
* @public
*
* @param {Function} callback The callback function will be called when the early access features are loaded.
* @param {Boolean} [force_reload] Whether to force a reload of the early access features.
* @param {String[]} [stages] The stages of the early access features to load.
*/
getEarlyAccessFeatures(callback: EarlyAccessFeatureCallback, force_reload?: boolean, stages?: EarlyAccessFeatureStage[]): void;
/**
* Exposes a set of events that PostHog will emit.
* e.g. `eventCaptured` is emitted immediately before trying to send an event
*
* Unlike `onFeatureFlags` and `onSessionId` these are not called when the
* listener is registered, the first callback will be the next event
* _after_ registering a listener
*
* Available events:
* - `eventCaptured`: Emitted immediately before trying to send an event
* - `featureFlagsReloading`: Emitted when feature flags are being reloaded (e.g. after `identify()`, `group()`, or `reloadFeatureFlags()`)
*
* {@label Capture}
*
* @example
* ```js
* posthog.on('eventCaptured', (event) => {
* console.log(event)
* })
* ```
*
* @example
* ```js
* // Track when feature flags are reloading to show a loading state
* posthog.on('featureFlagsReloading', () => {
* console.log('Feature flags are being reloaded...')
* })
* ```
*
* @public
*
* @param {String} event The event to listen for.
* @param {Function} cb The callback function to call when the event is emitted.
* @returns {Function} A function that can be called to unsubscribe the listener.
*/
on(event: 'eventCaptured' | 'featureFlagsReloading', cb: (...args: any[]) => void): () => void;
/**
* Register an event listener that runs when feature flags become available or when they change.
* If there are flags, the listener is called immediately in addition to being called on future changes.
* Note that this is not called only when we fetch feature flags from the server, but also when they change in the browser.
*
* {@label Feature flags}
*
* @public
*
* @example
* ```js
* posthog.onFeatureFlags(function(featureFlags, featureFlagsVariants, { errorsLoading }) {
* // do something
* })
* ```
*
* @param callback - The callback function will be called once the feature flags are ready or when they are updated.
* It'll return a list of feature flags enabled for the user, the variants,
* and also a context object indicating whether we succeeded to fetch the flags or not.
* @returns A function that can be called to unsubscribe the listener. Used by `useEffect` when the component unmounts.
*/
onFeatureFlags(callback: FeatureFlagsCallback): () => void;
/**
* Register an event listener that runs when surveys are loaded.
*
* Callback parameters:
* - surveys: Survey[]: An array containing all survey objects fetched from PostHog using the getSurveys method
* - context: { isLoaded: boolean, error?: string }: An object indicating if the surveys were loaded successfully
*
* {@label Surveys}
*
* @example
* ```js
* posthog.onSurveysLoaded((surveys, context) => { // do something })
* ```
*
* @param {SurveyCallback} callback The callback function will be called when surveys are loaded or updated.
* @returns A function that can be called to unsubscribe the listener.
*/
onSurveysLoaded(callback: SurveyCallback): () => void;
/**
* Register an event listener that runs whenever the session id or window id change.
* If there is already a session id, the listener is called immediately in addition to being called on future changes.
*
* Can be used, for example, to sync the PostHog session id with a backend session.
*
* {@label Identification}
*
* @public
*
* @example
* ```js
* posthog.onSessionId(function(sessionId, windowId) { // do something })
* ```
*
* @param {Function} [callback] The callback function will be called once a session id is present or when it or the window id are updated.
* @returns {Function} A function that can be called to unsubscribe the listener. E.g. Used by `useEffect` when the component unmounts.
*/
onSessionId(callback: SessionIdChangedCallback): () => void;
/**
* Get list of all surveys.
*
* {@label Surveys}
*
* @example
* ```js
* function callback(surveys, context) {
* // do something
* }
*
* posthog.getSurveys(callback, false)
* ```
*
* @public
*
* @param {SurveyCallback} callback Function that receives the array of surveys.
* @param {boolean} [forceReload] Optional boolean to force an API call for updated surveys.
*/
getSurveys(callback: SurveyCallback, forceReload?: boolean): void;
/**
* Get surveys that should be enabled for the current user. See [fetching surveys documentation](/docs/surveys/implementing-custom-surveys#fetching-surveys-manually) for more details.
*
* {@label Surveys}
*
* @example
* ```js
* posthog.getActiveMatchingSurveys((surveys) => {
* // do something
* })
* ```
*
* @public
*
* @param {SurveyCallback} callback The callback function will be called when the surveys are loaded or updated.
* @param {boolean} [forceReload] Whether to force a reload of the surveys.
*/
getActiveMatchingSurveys(callback: SurveyCallback, forceReload?: boolean): void;
/**
* Although we recommend using popover surveys and display conditions,
* if you want to show surveys programmatically without setting up all
* the extra logic needed for API surveys, you can render surveys
* programmatically with the renderSurvey method.
*
* This takes a survey ID and an HTML selector to render an unstyled survey.
*
* {@label Surveys}
*
* @example
* ```js
* posthog.renderSurvey(coolSurveyID, '#survey-container')
* ```
*
* @deprecated Use displaySurvey instead - it's more complete and also supports popover surveys.
*
* @public
*
* @param {String} surveyId The ID of the survey to render.
* @param {String} selector The selector of the HTML element to render the survey on.
*/
renderSurvey(surveyId: string, selector: string): void;
/**
* Display a survey programmatically as either a popover or inline element.
*
* @param {string} surveyId The survey ID to display.
* @param {DisplaySurveyOptions} [options] Display configuration. Defaults to a popover that respects dashboard conditions and delays.
*
* @example
* ```js
* // Display as popover (respects all conditions defined in the dashboard)
* posthog.displaySurvey('survey-id-123')
* ```
*
* @example
* ```js
* // Display inline in a specific element
* posthog.displaySurvey('survey-id-123', {
* displayType: DisplaySurveyType.Inline,
* ignoreConditions: false,
* ignoreDelay: false,
* selector: '#survey-container'
* })
* ```
*
* @example
* ```js
* // Force display ignoring conditions and delays
* posthog.displaySurvey('survey-id-123', {
* displayType: DisplaySurveyType.Popover,
* ignoreConditions: true,
* ignoreDelay: true
* })
* ```
*
* {@label Surveys}
*/
displaySurvey(surveyId: string, options?: DisplaySurveyOptions): void;
/**
* Cancels a pending survey that is waiting to be displayed (e.g., due to a popup delay).
*
* {@label Surveys}
*
* @param {string} surveyId The survey ID whose pending display should be cancelled.
*/
cancelPendingSurvey(surveyId: string): void;
/**
* Checks the feature flags associated with this Survey to see if the survey can be rendered.
* This method is deprecated because it's synchronous and won't return the correct result if surveys are not loaded.
* Use `canRenderSurveyAsync` instead.
*
* {@label Surveys}
*
* @public
* @deprecated
*
* @param surveyId The ID of the survey to check.
* @returns A SurveyRenderReason object indicating if the survey can be rendered.
*/
canRenderSurvey(surveyId: string): SurveyRenderReason | null;
/**
* Checks the feature flags associated with this Survey to see if the survey can be rendered.
*
* {@label Surveys}
*
* @example
* ```js
* posthog.canRenderSurveyAsync(surveyId).then((result) => {
* if (result.visible) {
* // Survey can be rendered
* console.log('Survey can be rendered')
* } else {
* // Survey cannot be rendered
* console.log('Survey cannot be rendered:', result.disabledReason)
* }
* })
* ```
*
* @public
*
* @param surveyId The ID of the survey to check.
* @param forceReload If true, the survey will be reloaded from the server, Default: false
* @returns A SurveyRenderReason object indicating if the survey can be rendered.
*/
canRenderSurveyAsync(surveyId: string, forceReload?: boolean): Promise<SurveyRenderReason>;
private _validateIdentifyId;
/**
* Associates a user with a unique identifier instead of an auto-generated ID.
* Learn more about [identifying users](/docs/product-analytics/identify)
*
* {@label Identification}
*
* @remarks
* By default, PostHog assigns each user a randomly generated `distinct_id`. Use this method to
* replace that ID with your own unique identifier (like a user ID from your database).
*
* @example
* ```js
* // basic identification
* posthog.identify('user_12345')
* ```
*
* @example
* ```js
* // identify with user properties
* posthog.identify('user_12345', {
* email: 'user@example.com',
* plan: 'premium'
* })
* ```
*
* @example
* ```js
* // identify with set and set_once properties
* posthog.identify('user_12345',
* { last_login: new Date() }, // updates every time
* { signup_date: new Date() } // sets only once
* )
* ```
*
* @public
*
* @param {String} [new_distinct_id] A string that uniquely identifies a user. If not provided, the distinct_id currently in the persistent store (cookie or localStorage) will be used.
* @param {Object} [userPropertiesToSet] Optional: An associative array of properties to store about the user. Note: For feature flag evaluations, if the same key is present in the userPropertiesToSetOnce,
* it will be overwritten by the value in userPropertiesToSet.
* @param {Object} [userPropertiesToSetOnce] Optional: An associative array of properties to store about the user. If property is previously set, this does not override that value.
*/
identify(new_distinct_id?: string, userPropertiesToSet?: Properties, userPropertiesToSetOnce?: Properties): void;
/**
* Sets properties on the person profile associated with the current `distinct_id`.
* Learn more about [identifying users](/docs/product-analytics/identify)
*
* {@label Identification}
*
* @remarks
* Updates user properties that are stored with the person profile in PostHog.
* If `person_profiles` is set to `identified_only` and no profile exists, this will create one.
*
* @example
* ```js
* // set user properties
* posthog.setPersonProperties({
* email: 'user@example.com',
* plan: 'premium'
* })
* ```
*
* @example
* ```js
* // set properties
* posthog.setPersonProperties(
* { name: 'Max Hedgehog' }, // $set properties
* { initial_url: '/blog' } // $set_once properties
* )
* ```
*
* @public
*
* @param {Object} [userPropertiesToSet] Optional: An associative array of properties to store about the user. Note: For feature flag evaluations, if the same key is present in the userPropertiesToSetOnce,
* it will be overwritten by the value in userPropertiesToSet.
* @param {Object} [userPropertiesToSetOnce] Optional: An associative array of properties to store about the user. If property is previously set, this does not override that value.
*/
setPersonProperties(userPropertiesToSet?: Properties, userPropertiesToSetOnce?: Properties): void;
/**
* Removes properties from the person profile associated with the current `distinct_id`.
* Learn more about [identifying users](/docs/product-analytics/identify)
*
* {@label Identification}
*
* @remarks
* Deletes the given person properties from the person profile in PostHog. This is the
* counterpart to {@link setPersonProperties} — instead of hand-passing `$unset` inside a
* `capture()` call, you can remove properties with a dedicated method.
* If `person_profiles` is set to `never`, this call is ignored.
*
* @example
* ```js
* // remove a single property
* posthog.unsetPersonProperties('plan')
* ```
*
* @example
* ```js
* // remove multiple properties
* posthog.unsetPersonProperties(['plan', 'email'])
* ```
*
* @public
*
* @param {String|String[]} propertyNames The name (or names) of the person properties to remove.
*/
unsetPersonProperties(propertyNames: string | string[]): void;
/**
* Associates the user with a group for group-based analytics.
* Learn more about [groups](/docs/product-analytics/group-analytics)
*
* {@label Identification}
*
* @remarks
* Groups allow you to analyze users collectively (e.g., by organization, team, or account).
* This sets the group association for all subsequent events and reloads feature flags.
*
* @example
* ```js
* // associate user with an organization
* posthog.group('organization', 'org_12345', {
* name: 'Acme Corp',
* plan: 'enterprise'
* })
* ```
*
* @example
* ```js
* // associate with multiple group types
* posthog.group('organization', 'org_12345')
* posthog.group('team', 'team_67890')
* ```
*
* @public
*
* @param {String} groupType Group type (example: 'organization')
* @param {String} groupKey Group key (example: 'org::5')
* @param {Object} groupPropertiesToSet Optional properties to set for group
*/
group(groupType: string, groupKey: string, groupPropertiesToSet?: Properties): void;
/**
* Resets only the group properties of the user currently logged in.
* Learn more about [groups](/docs/product-analytics/group-analytics)
*
* {@label Identification}
*
* @example
* ```js
* posthog.resetGroups()
* ```
*
* @public
*/
resetGroups(): void;
/**
* Sometimes, you might want to evaluate feature flags using properties that haven't been ingested yet,
* or were set incorrectly earlier. You can do so by setting properties the flag depends on with these calls:
*
* {@label Feature flags}
*
* @example
* ```js
* // Set properties
* posthog.setPersonPropertiesForFlags({'property1': 'value', property2: 'value2'})
* ```
*
* @example
* ```js
* // Set properties without reloading
* posthog.setPersonPropertiesForFlags({'property1': 'value', property2: 'value2'}, false)
* ```
*
* @public
*
* @param {Object} properties The properties to override.
* @param {Boolean} [reloadFeatureFlags] Whether to reload feature flags.
*/
setPersonPropertiesForFlags(properties: Properties, reloadFeatureFlags?: boolean): void;
/**
* Resets the person properties for feature flags.
*
* {@label Feature flags}
*
* @public
*
* @example
* ```js
* posthog.resetPersonPropertiesForFlags()
* ```
*
* @example
* ```js
* // Reset properties without reloading
* posthog.resetPersonPropertiesForFlags(false)
* ```
*
* @param {Boolean} [reloadFeatureFlags=true] Whether to reload feature flags.
*/
resetPersonPropertiesForFlags(reloadFeatureFlags?: boolean): void;
/**
* Set override group properties for feature flags.
* This is used when dealing with new groups / where you don't want to wait for ingestion
* to update properties.
* Takes in an object, the key of which is the group type.
*
* {@label Feature flags}
*
* @public
*
* @example
* ```js
* // Set properties with reload
* posthog.setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } })
* ```
*
* @example
* ```js
* // Set properties without reload
* posthog.setGroupPropertiesForFlags({'organization': { name: 'CYZ', employees: '11' } }, false)
* ```
*
* @param {Object} properties The properties to override, the key of which is the group type.
* @param {Boolean} [reloadFeatureFlags] Whether to reload feature flags.
*/
setGroupPropertiesForFlags(properties: {
[type: string]: Properties;
}, reloadFeatureFlags?: boolean): void;
/**
* Resets the group properties for feature flags.
*
* {@label Feature flags}
*
* @public
*
* @example
* ```js
* posthog.resetGroupPropertiesForFlags()
* ```
*
* @param {string} [group_type] Optional group type to reset. If omitted, all group properties are reset.
*/
resetGroupPropertiesForFlags(group_type?: string): void;
/**
* Resets all user data and starts a fresh session.
*
* ⚠️ **Warning**: Only call this when a user logs out. Calling at the wrong time can cause split sessions.
*
* This clears:
* - Session ID and super properties
* - User identification (sets new random distinct_id)
* - Cached data and consent settings
*
* ⚠️ **Warning**: because consent is cleared, `reset()` returns the instance to the default
* consent state. With `opt_out_capturing_by_default` that default is opted out,
* so calling `reset()` *after* `opt_in_capturing()` silently stops capturing.
* Always `reset()` first, then opt in.
*
* {@label Identification}
* @example
* ```js
* // reset on user logout
* function logout() {
* posthog.reset()
* // redirect to login page
* }
* ```
*
* @example
* ```js
* // reset and generate new device ID
* posthog.reset(true) // also resets device_id
* ```
*
* @example
* ```js
* // reset with a custom anonymous ID and bootstrapped feature flags
* posthog.reset({
* bootstrap: {
* distinctID: myAnonymousID,
* isIdentifiedID: false,
* featureFlags: { 'my-flag': true },
* }
* })
* ```
*
* @example
* ```js
* // with opt_out_capturing_by_default, reset() before opting in, never after
* posthog.reset()
* posthog.opt_in_capturing()
* ```
*
* @public
*
* @param options Boolean to reset the device ID (legacy), or reset options including bootstrap values.
*/
reset(options?: boolean | ResetOptions): void;
private _reset;
/**
* Flushes any queued events and resolves once teardown is complete.
*
* @remarks
* This exists primarily for parity with the server-side
* [Node.js SDK](/docs/libraries/node), whose `shutdown()` you call once before a
* process exits. In the browser there is no process to exit, so this method
* performs synchronous best-effort extension cleanup, flushes the request
* queues, and always resolves.
*
* It is safe to call in isomorphic teardown code (for example a Nuxt/Next module
* that calls `shutdown()` on both the server and the client) so the same
* symmetric cleanup works in either environment without throwing.
*
* {@label Lifecycle}
* @example
* ```js
* // symmetric teardown that runs on both server and client
* await posthog.shutdown()
* ```
*
* @public
*
* @param {number} [_shutdownTimeoutMs] Retained for parity with the Node.js SDK; ignored in browsers.
* @returns {Promise<void>} A promise that resolves once best-effort cleanup and queue flushing complete.
*/
shutdown(_shutdownTimeoutMs?: number): Promise<void>;
/**
* Set HMAC-based identity verification.
*
* @remarks
* When set, products like conversations use server-verified identity
* (distinct_id + HMAC hash) instead of anonymous session identifiers.
* The hash should be computed server-side as HMAC-SHA256 of the
* distinct_id using the project's API secret.
*
* @param distinctId - The verified user distinct_id
* @param hash - HMAC-SHA256 of distinctId using the project API secret
*
* @example
* ```js
* posthog.setIdentity('user_123', 'a1b2c3d4e5f6...')
* ```
*
* @public
*/
setIdentity(distinctId: string, hash: string): void;
/**
* Clear HMAC-based identity verification, reverting to anonymous mode.
*
* @example
* ```js
* posthog.clearIdentity()
* ```
*
* @public
*/
clearIdentity(): void;
/**
* Returns the current distinct ID for the user.
*
* @remarks
* This is either the auto-generated ID or the ID set via `identify()`.
* The distinct ID is used to associate events with users in PostHog.
*
* {@label Identification}
*
* @example
* ```js
* // get the current user ID
* const userId = posthog.get_distinct_id()
* console.log('Current user:', userId)
* ```
*
* @example
* ```js
* // use in loaded callback
* posthog.init('token', {
* loaded: (posthog) => {
* const id = posthog.get_distinct_id()
* // use the ID
* }
* })
* ```
*
* @public
*
* @returns The current distinct ID
*/
get_distinct_id(): string;
/**
* Returns the current groups.
*
* {@label Identification}
*
* @public
*
* @returns The current groups
*/
getGroups(): Record<string, any>;
/**
* Returns the current session_id.
*
* @remarks
* This should only be used for informative purposes.
* Any actual internal use case for the session_id should be handled by the sessionManager.
*
* @public
*
* @returns The stored session ID for the current session. This may be an empty string if the client is not yet fully initialized.
*/
get_session_id(): string;
/**
* Returns the Replay url for the current session.
*
* {@label Session replay}
*
* @public
*
* @example
* ```js
* // basic usage
* posthog.get_session_replay_url()
* ```
*
* @example
* ```js
* // timestamp
* posthog.get_session_replay_url({ withTimestamp: true })
* ```
*
* @example
* ```js
* // timestamp and lookback
* posthog.get_session_replay_url({
* withTimestamp: true,
* timestampLookBack: 30 // look back 30 seconds
* })
* ```
*
* @param {Object} [options] Options for the URL.
* @param {boolean} [options.withTimestamp] Whether to include the timestamp in the URL.
* @param {number} [options.timestampLookBack] How many seconds to look back for the timestamp.
* @returns The URL for the current session replay, or an empty string if sessions are unavailable.
*/
get_session_replay_url(options?: {
withTimestamp?: boolean;
timestampLookBack?: number;
}): string;
/**
* Creates an alias linking two distinct user identifiers. Learn more about [identifying users](/docs/product-analytics/identify)
*
* {@label Identification}
*
* @remarks
* PostHog will use this to link two distinct_ids going forward (not retroactively).
* Call this when a user signs up to connect their anonymous session with their account.
*
*
* @example
* ```js
* // link anonymous user to account on signup
* posthog.alias('user_12345')
* ```
*
* @example
* ```js
* // explicit alias with original ID
* posthog.alias('user_12345', 'anonymous_abc123')
* ```
*
* @public
*
* @param {String} alias A unique identifier that you want to use for this user in the future.
* @param {String} [original] The current identifier being used for this user.
* @returns The `$create_alias` capture result, `-1` if alias matches the current distinct ID, `-2` if aliasing would duplicate a People user, or void if person processing is disabled.
*/
alias(alias: string, original?: string): CaptureResult | void | number;
/**
* Updates the configuration of the PostHog instance.
*
* {@label Initialization}
*
* @public
*
* @param {Partial<PostHogConfig>} config A dictionary of new configuration values to update
*/
set_config(config: Partial<PostHogConfig>): void;
/**
* @internal
* Allows wrapper SDKs (e.g. posthog-flutter, posthog-react-native) to override the
* `$lib` and `$lib_version` properties sent with every event.
*
* This is not a public API and may change without notice.
*/
_overrideSDKInfo(sdkName: string, sdkVersion: string): void;
/**
* turns session recording on, and updates the config option `disable_session_recording` to false
*
* {@label Session replay}
*
* @public
*
* @example
* ```js
* // Start and ignore controls
* posthog.startSessionRecording(true)
* ```
*
* @example
* ```js
* // Start and override controls
* posthog.startSessionRecording({
* // you don't have to send all of these
* sampling: true || false,
* linked_flag: true || false,
* url_trigger: true || false,
* event_trigger: true || false
* })
* ```
*
* @param override.sampling - optional boolean to override the default sampling behavior - ensures the next session recording to start will not be skipped by sampling config.
* @param override.linked_flag - optional boolean to override the default linked_flag behavior - ensures the next session recording to start will not be skipped by linked_flag config.
* @param override.url_trigger - optional boolean to override the default url_trigger behavior - ensures the next session recording to start will not be skipped by url_trigger config.
* @param override.event_trigger - optional boolean to override the default event_trigger behavior - ensures the next session recording to start will not be skipped by event_trigger config.
* @param override - optional boolean to override the default sampling behavior - ensures the next session recording to start will not be skipped by sampling or linked_flag config. `true` is shorthand for { sampling: true, linked_flag: true }
*/
startSessionRecording(override?: {
sampling?: boolean;
linked_flag?: boolean;
url_trigger?: true;
event_trigger?: true;
} | true): void;
/**
* turns session recording off, and updates the config option
* disable_session_recording to true
*
* {@label Session replay}
*
* @public
*
* @example
* ```js
* // Stop session recording
* posthog.stopSessionRecording()
* ```
*/
stopSessionRecording(): void;
/**
* returns a boolean indicating whether session recording
* is currently running
*
* {@label Session replay}
*
* @public
*
* @example
* ```js
* // Stop session recording if it's running
* if (posthog.sessionRecordingStarted()) {
* posthog.stopSessionRecording()
* }
* ```
*
* @returns Whether session recording is currently running.
*/
sessionRecordingStarted(): boolean;
/**
* Capture a caught exception manually
*
* {@label Error tracking}
*
* @public
*
* @example
* ```js
* // Capture a caught exception
* try {
* // something that might throw
* } catch (error) {
* posthog.captureException(error)
* }
* ```
*
* @example
* ```js
* // With additional properties
* posthog.captureException(error, {
* customProperty: 'value',
* anotherProperty: ['I', 'can be a list'],
* ...
* })
* ```
*
* @param {unknown} error The error or exception-like value to capture.
* @param {Properties} [additionalProperties] Any additional properties to add to the error event.
* @returns The result of the capture, or undefined if exception capture is unavailable.
*/
captureException(error: unknown, additionalProperties?: Properties): CaptureResult | undefined;
/**
* Add a breadcrumb-like step that will be attached to the next captured exception.
*
* {@label Error tracking}
*
* @public
*
* @example
* ```js
* posthog.addExceptionStep('Checkout button clicked', {
* checkout_id: 'ch_123',
* })
* ```
*
* @param {string} message The step message.
* @param {Properties} [properties] Additional context for this step.
*/
addExceptionStep(message: string, properties?: Properties): void;
/**
* Capture a log entry and send it to the PostHog logs endpoint.
*
* {@label Logs}
*
* @public
*
* @example
* ```js
* posthog.captureLog({
* body: 'checkout completed',
* level: 'info',
* attributes: { order_id: 'ord_789', amount_cents: 4999 },
* })
* ```
*
* @param {CaptureLogOptions} options The log entry options
*/
captureLog(options: CaptureLogOptions): void;
private static _noopLogger;
/**
* Logger with convenience methods for each severity level.
*
* @example
* ```js
* posthog.logger.info('checkout completed', { order_id: 'ord_789' })
* posthog.logger.error('payment failed', { error_code: 'E001' })
* ```
*/
get logger(): _posthog_types.Logger;
/**
* turns exception autocapture on, and updates the config option `capture_exceptions` to the provided config (or `true`)
*
* {@label Error tracking}
*
* @public
*
* @example
* ```js
* // Start with default exception autocapture rules. No-op if already enabled
* posthog.startExceptionAutocapture()
* ```
*
* @example
* ```js
* // Start and override controls
* posthog.startExceptionAutocapture({
* // you don't have to send all of these (unincluded values will use the default)
* capture_unhandled_errors: true || false,
* capture_unhandled_rejections: true || false,
* capture_console_errors: true || false
* })
* ```
*
* @param config - optional configuration option to control the exception autocapture behavior
*/
startExceptionAutocapture(config?: ExceptionAutoCaptureConfig): void;
/**
* turns exception autocapture off by updating the config option `capture_exceptions` to `false`
*
* {@label Error tracking}
*
* @public
*
* @example
* ```js
* // Stop capturing exceptions automatically
* posthog.stopExceptionAutocapture()
* ```
*/
stopExceptionAutocapture(): void;
/**
* returns a boolean indicating whether the [toolbar](/docs/toolbar) loaded
*
* {@label Toolbar}
*
* @public
*
* @param {ToolbarParams} params Toolbar parameters.
* @returns Whether the toolbar loaded.
*/
loadToolbar(params: ToolbarParams): boolean;
/**
* Returns the value of a super property. Returns undefined if the property doesn't exist.
*
* {@label Identification}
*
* @remarks
* get_property() can only be called after the PostHog library has finished loading.
* init() has a loaded function available to handle this automatically.
*
* @example
* ```js
* // grab value for '$user_id' after the posthog library has loaded
* posthog.init('<YOUR PROJECT TOKEN>', {
* loaded: function(posthog) {
* user_id = posthog.get_property('$user_id');
* }
* });
* ```
* @public
*
* @param {String} property_name The name of the super property you want to retrieve
* @returns The stored property value, or undefined if it is not set.
*/
get_property(property_name: string): Property | undefined;
/**
* Returns the value of the session super property named property_name. If no such
* property is set, getSessionProperty() will return the undefined value.
*
* {@label Identification}
*
* @public
*
* @remarks
* This is based on browser-level `sessionStorage`, NOT the PostHog session.
* getSessionProperty() can only be called after the PostHog library has finished loading.
* init() has a loaded function available to handle this automatically.
*
* @example
* ```js
* // grab value for 'user_id' after the posthog library has loaded
* posthog.init('YOUR PROJECT TOKEN', {
* loaded: function(posthog) {
* user_id = posthog.getSessionProperty('user_id');
* }
* });
* ```
*
* @param {String} property_name The name of the session super property you want to retrieve
* @returns The stored session property value, or undefined if it is not set.
*/
getSessionProperty(property_name: string): Property | undefined;
/**
* Returns a string representation of the PostHog instance.
*
* {@label Initialization}
*
* @internal
*/
toString(): string;
_isIdentified(): boolean;
_hasPersonProcessing(): boolean;
_shouldCapturePageleave(): boolean;
/**
* Creates a person profile for the current user, if they don't already have one and config.person_profiles is set
* to 'identified_only'. Produces a warning and does not create a profile if config.person_profiles is set to
* 'never'. Learn more about [person profiles](/docs/product-analytics/identify)
*
* {@label Identification}
*
* @public
*
* @example
* ```js
* posthog.createPersonProfile()
* ```
*/
createPersonProfile(): void;
/**
* Marks the current user as a test user by setting the `$internal_or_test_user` person property to `true`.
* This also enables person processing for the current user.
*
* This is useful for using in a cohort your internal/test filters for your posthog org.
* @see https://posthog.com/tutorials/filter-internal-users
* Create a cohort with `$internal_or_test_user` IS SET, and set your internal test filters to be NOT IN that cohort.
*
* {@label Identification}
*
* @example
* ```js
* // Manually mark as test user
* posthog.setInternalOrTestUser()
*
* // Or use internal_or_test_user_hostname config for automatic detection
* posthog.init('token', { internal_or_test_user_hostname: 'localhost' })
* ```
*
* @public
*/
setInternalOrTestUser(): void;
/**
* Enables person processing if possible, returns true if it does so or already enabled, false otherwise
*
* @param function_name
*/
_requirePersonProcessing(function_name: string): boolean;
private _is_persistence_disabled;
private _sync_opt_out_with_persistence;
/**
* Opts the user into data capturing and persistence.
*
* {@label Privacy}
*
* @remarks
* Enables event tracking and data persistence (cookies/localStorage) for this PostHog instance.
* By default, captures an `$opt_in` event unless disabled.
*
* @example
* ```js
* // simple opt-in
* posthog.opt_in_capturing()
* ```
*
* @example
* ```js
* // opt-in with custom event and properties
* posthog.opt_in_capturing({
* captureEventName: 'Privacy Accepted',
* captureProperties: { source: 'banner' }
* })
* ```
*
* @example
* ```js
* // opt-in without capturing event
* posthog.opt_in_capturing({
* captureEventName: false
* })
* ```
*
* @public
*
* @param {Object} [options] A dictionary of opt-in options.
* @param {EventName | null | false} [options.captureEventName] Event name to use for capturing the opt-in action. Set to `null` or `false` to skip capturing the opt-in event. Defaults to `$opt_in`.
* @param {Properties} [options.captureProperties] Set of properties to capture along with the opt-in action.
*/
opt_in_capturing(options?: {
captureEventName?: EventName | null | false; /** event name to be used for capturing the opt-in action */
captureProperties?: Properties; /** set of properties to be captured along with the opt-in action */
}): void;
/**
* Opts the user out of data capturing and persistence.
*
* {@label Privacy}
*
* @remarks
* Disables event tracking and data persistence (cookies/localStorage) for this PostHog instance.
* If `opt_out_persistence_by_default` is true, SDK persistence will also be disabled.
*
* @example
* ```js
* // opt user out (e.g., on privacy settings page)
* posthog.opt_out_capturing()
* ```
*
* @public
*/
opt_out_capturing(): void;
/**
* Checks if the user has opted into data capturing.
*
* {@label Privacy}
*
* @remarks
* Returns the current consent status for event tracking and data persistence.
*
* @example
* ```js
* if (posthog.has_opted_in_capturing()) {
* // show analytics features
* }
* ```
*
* @public
*
* @returns {boolean} current opt-in status
*/
has_opted_in_capturing(): boolean;
/**
* Checks if the user has opted out of data capturing.
*
* {@label Privacy}
*
* @remarks
* Returns the current consent status for event tracking and data persistence.
*
* @example
* ```js
* if (posthog.has_opted_out_capturing()) {
* // disable analytics features
* }
* ```
*
* @public
*
* @returns {boolean} current opt-out status
*/
has_opted_out_capturing(): boolean;
/**
* Returns the explicit consent status of the user.
*
* @remarks
* This can be used to check if the user has explicitly opted in or out of data capturing, or neither. This does not
* take the default config options into account, only whether the user has made an explicit choice, so this can be
* used to determine whether to show an initial cookie banner or not.
*
* @example
* ```js
* const consentStatus = posthog.get_explicit_consent_status()
* if (consentStatus === "granted") {
* // user has explicitly opted in
* } else if (consentStatus === "denied") {
* // user has explicitly opted out
* } else if (consentStatus === "pending"){
* // user has not made a choice, show consent banner
* }
* ```
*
* @public
*
* @returns The current explicit consent status.
*/
get_explicit_consent_status(): 'granted' | 'denied' | 'pending';
/**
* Checks whether the PostHog library is currently capturing events.
*
* Usually this means that the user has not opted out of capturing, but the exact behaviour can be controlled by
* some config options.
*
* Additionally, if the cookieless_mode is set to `'on_reject'`, we will capture events in cookieless mode if the
* user has opted out or been defaulted to opt-out.
*
* {@label Privacy}
*
* @see {PostHogConfig.cookieless_mode}
* @see {PostHogConfig.opt_out_persistence_by_default}
* @see {PostHogConfig.respect_dnt}
*
* @returns {boolean} whether the posthog library is capturing events
*/
is_capturing(): boolean;
/**
* Clear the user's opt in/out status of data capturing and cookies/localstorage for this PostHog instance
*
* {@label Privacy}
*
* @public
*
*/
clear_opt_in_out_capturing(): void;
_is_bot(): boolean | undefined;
_captureInitialPageview(): void;
/**
* Enables or disables debug mode for detailed logging.
*
* @remarks
* Debug mode logs all PostHog calls to the browser console for troubleshooting.
* Can also be enabled by adding `?__posthog_debug=true` to the URL.
*
* {@label Initialization}
*
* @example
* ```js
* // enable debug mode
* posthog.debug(true)
* ```
*
* @example
* ```js
* // disable debug mode
* posthog.debug(false)
* ```
*
* @public
*
* @param {boolean} [debug] If true, will enable debug mode.
*/
debug(debug?: boolean): void;
/**
* Helper method to check if external API calls (flags/decide) should be disabled
* Handles migration from old `advanced_disable_decide` to new `advanced_disable_flags`
*/
_shouldDisableFlags(): boolean;
private _runBeforeSend;
/**
* Returns the current page view ID.
*
* {@label Initialization}
*
* @public
*
* @returns The current page view ID, or undefined if no page view has been captured.
*/
getPageViewId(): string | undefined;
/**
* Capture written user feedback for a LLM trace. Numeric values are converted to strings.
*
* {@label LLM analytics}
*
* @public
*
* @param traceId The trace ID to capture feedback for.
* @param userFeedback The feedback to capture.
*/
captureTraceFeedback(traceId: string | number, userFeedback: string): void;
/**
* Capture a metric for a LLM trace. Numeric values are converted to strings.
*
* {@label LLM analytics}
*
* @public
*
* @param traceId The trace ID to capture the metric for.
* @param metricName The name of the metric to capture.
* @param metricValue The value of the metric to capture.
*/
captureTraceMetric(traceId: string | number, metricName: string, metricValue: string | number | boolean): void;
private _checkLocalStorageForDebug;
}
/**
* Pre-grouped extension bundles for tree-shaking support.
*
* Each bundle is self-contained: a feature plus its runtime dependencies.
* Use these with `__extensionClasses` to control which extensions are included in your bundle.
* The default `posthog-js` entrypoint includes all extensions. When using `posthog-js/slim`,
* you can import only the bundles you need:
*
* @example
* ```ts
* import posthog from 'posthog-js/slim'
* import { SessionReplayExtensions, AnalyticsExtensions } from 'posthog-js/extensions'
*
* posthog.init('ph_key', {
* __extensionClasses: {
* ...SessionReplayExtensions,
* ...AnalyticsExtensions,
* }
* })
* ```
*
* @module
*/
/** Feature flags. */
declare const FeatureFlagsExtensions: {
readonly featureFlags: typeof PostHogFeatureFlags;
};
/** Session replay. */
declare const SessionReplayExtensions: {
readonly sessionRecording: typeof SessionRecording;
};
/** Autocapture, click tracking, heatmaps, and web vitals. */
declare const AnalyticsExtensions: {
readonly autocapture: typeof BrowserAutocapture;
readonly historyAutocapture: typeof HistoryAutocapture;
readonly heatmaps: typeof Heatmaps;
readonly deadClicksAutocapture: typeof DeadClicksAutocapture;
readonly webVitalsAutocapture: typeof WebVitalsAutocapture;
};
/** Exception and error capture. Requires both the observer (capture hook) and exceptions (forwarding). */
declare const ErrorTrackingExtensions: {
readonly exceptionObserver: typeof ExceptionObserver;
readonly exceptions: typeof PostHogExceptions;
};
/** In-app product tours. Includes feature flags for targeting. */
declare const ProductToursExtensions: {
readonly featureFlags: typeof PostHogFeatureFlags;
readonly productTours: typeof PostHogProductTours;
};
/** Site apps support. */
declare const SiteAppsExtensions: {
readonly siteApps: typeof SiteApps;
};
/** Distributed tracing header injection. */
declare const TracingExtensions: {
readonly tracingHeaders: typeof TracingHeaders;
};
/** In-app surveys. Includes feature flags for targeting. */
declare const SurveysExtensions: {
readonly featureFlags: typeof PostHogFeatureFlags;
readonly surveys: typeof BrowserSurveys;
};
/** PostHog toolbar for visual element inspection and action setup. */
declare const ToolbarExtensions: {
readonly toolbar: typeof Toolbar;
};
/** Web experiments. Includes feature flags for variant evaluation. */
declare const ExperimentsExtensions: {
readonly featureFlags: typeof PostHogFeatureFlags;
readonly experiments: typeof WebExperiments;
};
/** In-app conversations. */
declare const ConversationsExtensions: {
readonly conversations: typeof PostHogConversations;
};
/** Console log capture. */
declare const LogsExtensions: {
readonly logs: typeof PostHogLogs;
};
/** The posthog.metrics API (count, gauge, histogram). */
declare const MetricsExtensions: {
readonly metrics: typeof PostHogMetrics;
};
/** All extensions — equivalent to the default `posthog-js` bundle. */
declare const AllExtensions: {
readonly metrics: typeof PostHogMetrics;
readonly logs: typeof PostHogLogs;
readonly conversations: typeof PostHogConversations;
readonly featureFlags: typeof PostHogFeatureFlags;
readonly experiments: typeof WebExperiments;
readonly toolbar: typeof Toolbar;
readonly tracingHeaders: typeof TracingHeaders;
readonly surveys: typeof BrowserSurveys;
readonly siteApps: typeof SiteApps;
readonly productTours: typeof PostHogProductTours;
readonly exceptionObserver: typeof ExceptionObserver;
readonly exceptions: typeof PostHogExceptions;
readonly autocapture: typeof BrowserAutocapture;
readonly historyAutocapture: typeof HistoryAutocapture;
readonly heatmaps: typeof Heatmaps;
readonly deadClicksAutocapture: typeof DeadClicksAutocapture;
readonly webVitalsAutocapture: typeof WebVitalsAutocapture;
readonly sessionRecording: typeof SessionRecording;
};
declare const extensionBundles_d_AllExtensions: typeof AllExtensions;
declare const extensionBundles_d_AnalyticsExtensions: typeof AnalyticsExtensions;
declare const extensionBundles_d_ConversationsExtensions: typeof ConversationsExtensions;
declare const extensionBundles_d_ErrorTrackingExtensions: typeof ErrorTrackingExtensions;
declare const extensionBundles_d_ExperimentsExtensions: typeof ExperimentsExtensions;
declare const extensionBundles_d_FeatureFlagsExtensions: typeof FeatureFlagsExtensions;
declare const extensionBundles_d_LogsExtensions: typeof LogsExtensions;
declare const extensionBundles_d_MetricsExtensions: typeof MetricsExtensions;
declare const extensionBundles_d_ProductToursExtensions: typeof ProductToursExtensions;
declare const extensionBundles_d_SessionReplayExtensions: typeof SessionReplayExtensions;
declare const extensionBundles_d_SiteAppsExtensions: typeof SiteAppsExtensions;
declare const extensionBundles_d_SurveysExtensions: typeof SurveysExtensions;
declare const extensionBundles_d_ToolbarExtensions: typeof ToolbarExtensions;
declare const extensionBundles_d_TracingExtensions: typeof TracingExtensions;
declare namespace extensionBundles_d {
export {
extensionBundles_d_AllExtensions as AllExtensions,
extensionBundles_d_AnalyticsExtensions as AnalyticsExtensions,
extensionBundles_d_ConversationsExtensions as ConversationsExtensions,
extensionBundles_d_ErrorTrackingExtensions as ErrorTrackingExtensions,
extensionBundles_d_ExperimentsExtensions as ExperimentsExtensions,
extensionBundles_d_FeatureFlagsExtensions as FeatureFlagsExtensions,
extensionBundles_d_LogsExtensions as LogsExtensions,
extensionBundles_d_MetricsExtensions as MetricsExtensions,
extensionBundles_d_ProductToursExtensions as ProductToursExtensions,
extensionBundles_d_SessionReplayExtensions as SessionReplayExtensions,
extensionBundles_d_SiteAppsExtensions as SiteAppsExtensions,
extensionBundles_d_SurveysExtensions as SurveysExtensions,
extensionBundles_d_ToolbarExtensions as ToolbarExtensions,
extensionBundles_d_TracingExtensions as TracingExtensions,
};
}
declare module '@posthog/types' {
interface TreeShakeableConfig {
optional: true;
}
}
declare const posthog: PostHog;
export { extensionBundles_d as BundleTypes, DEFAULT_PRODUCT_TOUR_APPEARANCE, PostHog, ProductTourEventName, ProductTourEventProperties, posthog as default, posthog, severityLevels };
export type { ConversationsTraits, ConversationsUnavailableReason, ConversationsWidgetState, DisplaySurveyOptions, DisplaySurveyPopoverOptions, ErrorEventArgs, EventHandler, FlagsResponse, GetMessagesResponse, GetTicketsOptions, GetTicketsResponse, JSONContent, MarkAsReadResponse, Message, MessageAuthorType, OverrideConfig, PersistentStore, PostHogConfig, PostHogInterface, ProductTour, ProductTourAppearance, ProductTourBannerConfig, ProductTourButtonAction, ProductTourCallback, ProductTourConditions, ProductTourDismissReason, ProductTourDisplayFrequency, ProductTourRenderReason, ProductTourSelectorError, ProductTourStep, ProductTourStepButton, ProductTourStepButtons, ProductTourStepTranslation, ProductTourStepType, ProductTourSurveyQuestion, ProductTourSurveyQuestionType, ProductTourType, ProductTourWaitPeriod, QueuedRequestWithOptions, RemoteConfigResult, RequestRestoreLinkPayload, RequestRestoreLinkResponse, RequestWithOptions, RestoreFromTokenPayload, RestoreFromTokenResponse, RestoreFromTokenStatus, RetriableRequestWithOptions, SendMessagePayload, SendMessageResponse, SessionContext, SessionRecordingPersistedConfig, SessionStartReason, ShowTourOptions, SiteApp, SiteAppGlobals, SiteAppLoader, SnippetArrayItem, SurveyCallback, SurveyConfig, SurveyElement, SurveyResponseValue, Ticket, TicketStatus, TipTapDoc, TipTapMark, TipTapNode, UserProvidedTraits };