posthog-js
Version:
Posthog-js allows you to automatically capture usage and send events to PostHog.
450 lines • 23.5 kB
JavaScript
(function () {var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react")) : typeof define === "function" && define.amd ? define(["exports", "react"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.PosthogReactSlim = {}, global.React));
})(this, function (exports, react) {
"use strict";
var _a;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = function (to, from, except, desc) {
if (from && typeof from === "object" || typeof from === "function")
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, {
get: (function (k) { return from[k]; }).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = function (mod, isNodeMode, target) { return (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod)); };
react = __toESM(react);
var GLOBAL_KEY = "__POSTHOG_REACT_SHARED_STATE__";
var globalObject = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : {};
var statesByReact;
try {
statesByReact = globalObject[GLOBAL_KEY] = globalObject[GLOBAL_KEY] || new WeakMap();
}
catch (_b) {
statesByReact = new WeakMap();
}
if (!statesByReact.has(react.createContext))
statesByReact.set(react.createContext, {});
var sharedState = statesByReact.get(react.createContext);
if (!sharedState.context)
sharedState.context = (0, react.createContext)({
get client() {
return sharedState.defaultPostHogInstance;
},
bootstrap: void 0
});
var PostHogContext = sharedState.context;
function PostHogProvider(_b) {
var client = _b.client, children = _b.children;
var value = (0, react.useMemo)(function () {
var _b;
return ({
client: client,
bootstrap: (_b = client.config) === null || _b === void 0 ? void 0 : _b.bootstrap
});
}, [client]);
return react.default.createElement(PostHogContext.Provider, { value: value }, children);
}
var isFunction = function (f) {
return typeof f === "function";
};
var isUndefined = function (x) {
return x === void 0;
};
var isNull = function (x) {
return x === null;
};
function useFeatureFlagEnabled(flag, defaultValue) {
var _b, _c;
var _d = (0, react.useContext)(PostHogContext), client = _d.client, bootstrap = _d.bootstrap;
var _e = (0, react.useState)(function () { return client.isFeatureEnabled(flag); }), featureEnabled = _e[0], setFeatureEnabled = _e[1];
(0, react.useEffect)(function () {
return client.onFeatureFlags(function () {
setFeatureEnabled(client.isFeatureEnabled(flag));
});
}, [client, flag]);
var bootstrapped = (_b = bootstrap === null || bootstrap === void 0 ? void 0 : bootstrap.featureFlags) === null || _b === void 0 ? void 0 : _b[flag];
if (!((_c = client === null || client === void 0 ? void 0 : client.featureFlags) === null || _c === void 0 ? void 0 : _c.hasLoadedFlags) && (bootstrap === null || bootstrap === void 0 ? void 0 : bootstrap.featureFlags))
return isUndefined(bootstrapped) ? defaultValue : !!bootstrapped;
return isUndefined(featureEnabled) ? defaultValue : featureEnabled;
}
function useFeatureFlagPayload(flag) {
var _b;
var _c = (0, react.useContext)(PostHogContext), client = _c.client, bootstrap = _c.bootstrap;
var _d = (0, react.useState)(function () { var _b; return (_b = client.getFeatureFlagResult(flag, { send_event: false })) === null || _b === void 0 ? void 0 : _b.payload; }), featureFlagPayload = _d[0], setFeatureFlagPayload = _d[1];
(0, react.useEffect)(function () {
return client.onFeatureFlags(function () {
var _b;
setFeatureFlagPayload((_b = client.getFeatureFlagResult(flag, { send_event: false })) === null || _b === void 0 ? void 0 : _b.payload);
});
}, [client, flag]);
if (!((_b = client === null || client === void 0 ? void 0 : client.featureFlags) === null || _b === void 0 ? void 0 : _b.hasLoadedFlags) && (bootstrap === null || bootstrap === void 0 ? void 0 : bootstrap.featureFlagPayloads))
return bootstrap.featureFlagPayloads[flag];
return featureFlagPayload;
}
function useFeatureFlagResult(flag) {
var _b, _c;
var _d = (0, react.useContext)(PostHogContext), client = _d.client, bootstrap = _d.bootstrap;
var _e = (0, react.useState)(function () { return client.getFeatureFlagResult(flag); }), result = _e[0], setResult = _e[1];
(0, react.useEffect)(function () {
return client.onFeatureFlags(function () {
setResult(client.getFeatureFlagResult(flag));
});
}, [client, flag]);
if (!((_b = client === null || client === void 0 ? void 0 : client.featureFlags) === null || _b === void 0 ? void 0 : _b.hasLoadedFlags) && (bootstrap === null || bootstrap === void 0 ? void 0 : bootstrap.featureFlags)) {
var bootstrappedValue = bootstrap.featureFlags[flag];
if (isUndefined(bootstrappedValue))
return;
return {
key: flag,
enabled: typeof bootstrappedValue === "string" ? true : !!bootstrappedValue,
variant: typeof bootstrappedValue === "string" ? bootstrappedValue : void 0,
payload: (_c = bootstrap.featureFlagPayloads) === null || _c === void 0 ? void 0 : _c[flag]
};
}
return result;
}
function useActiveFeatureFlags() {
var _b;
var _c = (0, react.useContext)(PostHogContext), client = _c.client, bootstrap = _c.bootstrap;
var _d = (0, react.useState)(function () { return client.featureFlags.getFlags(); }), featureFlags = _d[0], setFeatureFlags = _d[1];
(0, react.useEffect)(function () {
return client.onFeatureFlags(function (flags) {
setFeatureFlags(flags);
});
}, [client]);
if (!((_b = client === null || client === void 0 ? void 0 : client.featureFlags) === null || _b === void 0 ? void 0 : _b.hasLoadedFlags) && (bootstrap === null || bootstrap === void 0 ? void 0 : bootstrap.featureFlags))
return Object.entries(bootstrap.featureFlags).filter(function (_b) {
var value = _b[1];
return value;
}).map(function (_b) {
var key = _b[0];
return key;
});
return featureFlags;
}
function useFeatureFlagVariantKey(flag) {
var _b;
var _c = (0, react.useContext)(PostHogContext), client = _c.client, bootstrap = _c.bootstrap;
var _d = (0, react.useState)(function () { return client.getFeatureFlag(flag); }), featureFlagVariantKey = _d[0], setFeatureFlagVariantKey = _d[1];
(0, react.useEffect)(function () {
return client.onFeatureFlags(function () {
setFeatureFlagVariantKey(client.getFeatureFlag(flag));
});
}, [client, flag]);
if (!((_b = client === null || client === void 0 ? void 0 : client.featureFlags) === null || _b === void 0 ? void 0 : _b.hasLoadedFlags) && (bootstrap === null || bootstrap === void 0 ? void 0 : bootstrap.featureFlags))
return bootstrap.featureFlags[flag];
return featureFlagVariantKey;
}
var usePostHog = function () {
var client = (0, react.useContext)(PostHogContext).client;
return client;
};
function VisibilityAndClickTracker(_b) {
var children = _b.children, onIntersect = _b.onIntersect, onClick = _b.onClick, trackView = _b.trackView, options = _b.options, props = __rest(_b, ["children", "onIntersect", "onClick", "trackView", "options"]);
var ref = (0, react.useRef)(null);
var observerOptions = (0, react.useMemo)(function () { return (__assign({ threshold: .1 }, options)); }, [
options === null || options === void 0 ? void 0 : options.threshold,
options === null || options === void 0 ? void 0 : options.root,
options === null || options === void 0 ? void 0 : options.rootMargin
]);
(0, react.useEffect)(function () {
if (isNull(ref.current) || !trackView)
return;
var observer = new IntersectionObserver(function (_b) {
var entry = _b[0];
return onIntersect(entry);
}, observerOptions);
observer.observe(ref.current);
return function () { return observer.disconnect(); };
}, [
observerOptions,
trackView,
onIntersect
]);
return react.default.createElement("div", __assign(__assign({ ref: ref }, props), { onClick: onClick }), children);
}
function VisibilityAndClickTrackers(_b) {
var children = _b.children, trackInteraction = _b.trackInteraction, trackView = _b.trackView, options = _b.options, onInteract = _b.onInteract, onView = _b.onView, props = __rest(_b, ["children", "trackInteraction", "trackView", "options", "onInteract", "onView"]);
var clickTrackedRef = (0, react.useRef)(false);
var visibilityTrackedRef = (0, react.useRef)(false);
var cachedOnClick = (0, react.useCallback)(function () {
if (!clickTrackedRef.current && trackInteraction && onInteract) {
onInteract();
clickTrackedRef.current = true;
}
}, [trackInteraction, onInteract]);
var onIntersect = function (entry) {
if (!visibilityTrackedRef.current && entry.isIntersecting && onView) {
onView();
visibilityTrackedRef.current = true;
}
};
var trackedChildren = react.Children.map(children, function (child) {
return react.default.createElement(VisibilityAndClickTracker, __assign({ onClick: cachedOnClick, onIntersect: onIntersect, trackView: trackView, options: options }, props), child);
});
return react.default.createElement(react.default.Fragment, null, trackedChildren);
}
function PostHogFeature(_b) {
var flag = _b.flag, match = _b.match, children = _b.children, fallback = _b.fallback, visibilityObserverOptions = _b.visibilityObserverOptions, trackInteraction = _b.trackInteraction, trackView = _b.trackView, props = __rest(_b, ["flag", "match", "children", "fallback", "visibilityObserverOptions", "trackInteraction", "trackView"]);
var payload = useFeatureFlagPayload(flag);
var variant = useFeatureFlagVariantKey(flag);
var posthog = usePostHog();
var shouldTrackInteraction = trackInteraction !== null && trackInteraction !== void 0 ? trackInteraction : true;
var shouldTrackView = trackView !== null && trackView !== void 0 ? trackView : true;
if (!isUndefined(variant)) {
if (isUndefined(match) ? variant !== false : variant === match) {
var childNode = isFunction(children) ? children(payload) : children;
return react.default.createElement(VisibilityAndClickTrackers, __assign({ flag: flag, options: visibilityObserverOptions, trackInteraction: shouldTrackInteraction, trackView: shouldTrackView, onInteract: function () { return captureFeatureInteraction({
flag: flag,
posthog: posthog,
flagVariant: variant
}); }, onView: function () { return captureFeatureView({
flag: flag,
posthog: posthog,
flagVariant: variant
}); } }, props), childNode);
}
}
return react.default.createElement(react.default.Fragment, null, fallback);
}
function captureFeatureEvent(event, _b) {
var _c;
var flag = _b.flag, posthog = _b.posthog, flagVariant = _b.flagVariant;
var properties = {
feature_flag: flag,
$set: (_c = {}, _c["".concat(event, "/").concat(flag)] = flagVariant !== null && flagVariant !== void 0 ? flagVariant : true, _c)
};
if (typeof flagVariant === "string")
properties.feature_flag_variant = flagVariant;
posthog.capture(event, properties);
}
function captureFeatureInteraction(options) {
captureFeatureEvent("$feature_interaction", options);
}
function captureFeatureView(options) {
captureFeatureEvent("$feature_view", options);
}
function TrackedChild(_b) {
var child = _b.child, index = _b.index, name = _b.name, properties = _b.properties, observerOptions = _b.observerOptions;
var trackedRef = (0, react.useRef)(false);
var posthog = usePostHog();
var onIntersect = (0, react.useCallback)(function (entry) {
if (entry.isIntersecting && !trackedRef.current) {
posthog.capture("$element_viewed", __assign({ element_name: name, child_index: index }, properties));
trackedRef.current = true;
}
}, [
posthog,
name,
index,
properties
]);
return react.default.createElement(VisibilityAndClickTracker, {
onIntersect: onIntersect,
trackView: true,
options: observerOptions
}, child);
}
function PostHogCaptureOnViewed(_b) {
var name = _b.name, properties = _b.properties, observerOptions = _b.observerOptions, trackAllChildren = _b.trackAllChildren, children = _b.children, props = __rest(_b, ["name", "properties", "observerOptions", "trackAllChildren", "children"]);
var trackedRef = (0, react.useRef)(false);
var posthog = usePostHog();
var onIntersect = (0, react.useCallback)(function (entry) {
if (entry.isIntersecting && !trackedRef.current) {
posthog.capture("$element_viewed", __assign({ element_name: name }, properties));
trackedRef.current = true;
}
}, [
posthog,
name,
properties
]);
if (trackAllChildren) {
var trackedChildren = react.Children.map(children, function (child, index) {
return react.default.createElement(TrackedChild, {
key: index,
child: child,
index: index,
name: name,
properties: properties,
observerOptions: observerOptions
});
});
return react.default.createElement("div", props, trackedChildren);
}
return react.default.createElement(VisibilityAndClickTracker, __assign({ onIntersect: onIntersect, trackView: true, options: observerOptions }, props), children);
}
var isError = function (value) {
var tag = Object.prototype.toString.call(value);
return value instanceof Error || tag === "[object Error]" || tag === "[object Exception]" || tag === "[object DOMException]" || tag === "[object DOMError]";
};
var defineErrorName = function (error, name) {
try {
Object.defineProperty(error, "name", {
value: name,
writable: true,
enumerable: true,
configurable: true
});
}
catch (_b) { }
};
var setCause = function (error, cause) {
var seenErrors = new WeakSet();
var currentError = error;
while (!seenErrors.has(currentError)) {
seenErrors.add(currentError);
if (!isError(currentError.cause)) {
if (!isUndefined(currentError.cause))
cause.cause = currentError.cause;
currentError.cause = cause;
return;
}
currentError = currentError.cause;
}
};
var addReactComponentStack = function (error, componentStack) {
if (!componentStack)
return error;
var componentStackError = new Error(isError(error) ? error.message : "Primitive value captured as exception: ".concat(String(error)));
defineErrorName(componentStackError, "React ErrorBoundary ".concat(isError(error) ? error.name : "Error"));
componentStackError.stack = componentStack;
if (isError(error)) {
setCause(error, componentStackError);
return error;
}
return componentStackError;
};
var INITIAL_STATE = {
componentStack: null,
exceptionEvent: null,
error: null
};
var __POSTHOG_ERROR_MESSAGES = { INVALID_FALLBACK: "[PostHog.js][PostHogErrorBoundary] Invalid fallback prop, provide a valid React element or a function that returns a valid React element." };
var PostHogErrorBoundary = (_a = (function (_super) {
__extends(class_1, _super);
function class_1(props) {
var _this = _super.call(this, props) || this;
_this._resetError = function () {
_this.setState(INITIAL_STATE);
};
_this.state = INITIAL_STATE;
return _this;
}
class_1.prototype.componentDidCatch = function (error, errorInfo) {
var additionalProperties = this.props.additionalProperties;
var currentProperties;
if (isFunction(additionalProperties))
currentProperties = additionalProperties(error, errorInfo);
else if (typeof additionalProperties === "object")
currentProperties = additionalProperties;
var client = this.context.client;
var componentStack = errorInfo.componentStack;
var exceptionEvent = client.captureException(addReactComponentStack(error, componentStack), currentProperties);
this.setState({
error: error,
componentStack: componentStack !== null && componentStack !== void 0 ? componentStack : null,
exceptionEvent: exceptionEvent
});
};
class_1.prototype.render = function () {
var _b = this.props, children = _b.children, fallback = _b.fallback;
var state = this.state;
if (state.componentStack == null)
return isFunction(children) ? children() : children;
var element = isFunction(fallback) ? react.default.createElement(fallback, {
error: state.error,
componentStack: state.componentStack,
exceptionEvent: state.exceptionEvent,
resetError: this._resetError
}) : fallback;
if (react.default.isValidElement(element))
return element;
console.warn(__POSTHOG_ERROR_MESSAGES.INVALID_FALLBACK);
return react.default.createElement(react.default.Fragment, null);
};
return class_1;
}(react.default.Component)),
__setFunctionName(_a, "PostHogErrorBoundary"),
(function () {
_a.contextType = PostHogContext;
})(),
_a);
var setupReactErrorHandler = function (client, callback) {
return function (error, errorInfo) {
var event = client.captureException(addReactComponentStack(error, errorInfo.componentStack));
if (callback)
callback(event, error, errorInfo);
};
};
exports.PostHogCaptureOnViewed = PostHogCaptureOnViewed;
exports.PostHogContext = PostHogContext;
exports.PostHogErrorBoundary = PostHogErrorBoundary;
exports.PostHogFeature = PostHogFeature;
exports.PostHogProvider = PostHogProvider;
exports.captureFeatureInteraction = captureFeatureInteraction;
exports.captureFeatureView = captureFeatureView;
exports.setupReactErrorHandler = setupReactErrorHandler;
exports.useActiveFeatureFlags = useActiveFeatureFlags;
exports.useFeatureFlagEnabled = useFeatureFlagEnabled;
exports.useFeatureFlagPayload = useFeatureFlagPayload;
exports.useFeatureFlagResult = useFeatureFlagResult;
exports.useFeatureFlagVariantKey = useFeatureFlagVariantKey;
exports.usePostHog = usePostHog;
});
}).call(this);
//# sourceMappingURL=index.js.map