Compare Versions - posthog-js
npm / posthog-js / Compare Versions
1.404.1
Patch Changes
- #4191
66c1666Thanks @turnipdabeets! - Honour the project-level autocapture opt-out when the remote config request fails. Previously a failed config fetch (network error, timeout, blocked request) enabled autocapture on opted-out projects and persisted that state for later page loads. Autocapture now keeps the last successfully received server value, and stays off until the first successful config response. (2026-07-17)
1.404.0
Minor Changes
- #4149
607bf54Thanks @pauldambra! - Add dead swipe detection to dead clicks autocapture. When dead clicks autocapture is enabled, touch swipe gestures that produce no observable screen change (no scroll, mutation, selection or visibility change) are now captured as$dead_swipeevents, surfacing failed navigations on touch devices. Configurable viacapture_dead_swipes(defaulttrue) andswipe_threshold_px(default30) on thecapture_dead_clicksconfig. Swipes over surfaces whose response cannot be observed (canvas, video and other media elements under the finger) are skipped, and captures are limited per page load viamax_dead_swipes_per_page_load(default10). (2026-07-16)
Patch Changes
- #4171
df17ddcThanks @posthog! - Catch synchronous throws from a monkey-patchedwindow.fetchso they no longer escape as unhandled exceptions. A synchronous throw is now routed through the same handling as an async rejection, so the request queue retries instead of the error leaking into error tracking. (2026-07-16) - Updated dependencies [
607bf54]:- @posthog/types@1.397.0
1.403.0
Minor Changes
-
#4159
fad6d9aThanks @haacked! - add$feature_flag_has_experimentto$feature_flag_calledevents$feature_flag_calledevents now carry a$feature_flag_has_experimentboolean sourced from the server'shas_experimentflag metadata (the/flags?v=2response for remote evaluation, the/api/feature_flag/local_evaluationdefinitions for posthog-node local evaluation). The property is only sent when the server explicitly reportshas_experiment; it is omitted entirely when the value is unknown (older servers, missing metadata, bootstrapped or locally injected flags). (2026-07-16)
Patch Changes
- Updated dependencies [
fad6d9a]:- @posthog/core@1.43.0
- @posthog/types@1.396.0
1.402.3
Patch Changes
-
#4157
4a2ecf5Thanks @posthog! - Session recording no longer emits an uncaughtNotAllowedError("Sharing constructed stylesheets in multiple documents is not allowed") when a page assigns aCSSStyleSheetconstructed in a different document toadoptedStyleSheets. That assignment is the host page's own invalid operation, but the recorder's patched setter sat on the call stack, so the exception was attributed to rrweb and churned fingerprints in error tracking. The recorder now contains this specific rejection (matched by its standardizedNotAllowedErrorname, so it works even when the setter throws from an iframe realm) and skips recording those sheets, while still re-throwing any other native-setter error so host-page behaviour is preserved. (2026-07-15) -
#4158
0dc389eThanks @posthog! - fix(replay): session recording no longer throwsTypeError: Converting circular structure to JSONwhen replay event data contains a circular reference. The circular-reference guard now also detects cycles that pass through an array, and affected events are captured with[Circular]markers instead of surfacing an unhandled error and being dropped. (2026-07-15) -
Updated dependencies [
fc2cb2e]:- @posthog/core@1.42.1
1.402.2
Patch Changes
- #4151
81adbfdThanks @posthog! - Session recording no longer emits an uncaughtTypeError: Illegal invocationwhen a programmatic input-value change happens on an object that is not a genuine native input element (for example a proxy on the element prototype chain). The recorder drops that one replay update instead of throwing. (2026-07-15)
1.402.1
Patch Changes
-
#4117
1eddff7Thanks @DanielVisca! - add the posthog.metrics API (count, gauge, histogram) to posthog-node — alphaBackend services can now record metrics through the same statsd-style pre-aggregating client the browser SDK ships, with no OpenTelemetry setup:
const client = new PostHog('phc_...', { metrics: { serviceName: 'billing-worker' } }) client.metrics.count('invoices.processed', 1, { attributes: { plan: 'pro' } }) client.metrics.gauge('queue.depth', 42) client.metrics.histogram('job.duration', 187, { unit: 'ms' })Samples aggregate in memory and flush as OTLP/JSON to
/i/v1/metrics(one data point per series per window). Pending metrics are flushed onshutdown(). Core gains_sendMetricsBatchonPostHogCoreStateless(same outcome contract as_sendLogsBatch) and a sharedresolveMetricsConfig, so any core-based SDK can hostPostHogMetrics. (2026-07-15) -
Updated dependencies [
1eddff7]:- @posthog/core@1.42.0
1.402.0
Minor Changes
- #4143
0e8ad14Thanks @robbie-c! - Stamp the current hostname as$snapshot_hoston every$snapshotevent the session recorder sends. The value is derived from the page URL after it passes through the existing replay URL masking pipeline (maskCapturedNetworkRequestFn/ deprecatedmaskNetworkRequestFn, hash stripping, personal-data query-param masking), so it cannot bypass a customer's masking config. When masking removes the URL or the masked result doesn't parse as a URL, the property is omitted entirely. This gives ingestion consumers a per-message host signal even for mid-session snapshot batches that contain no URL-bearing events. (2026-07-15)
1.401.0
Minor Changes
- #4129
800af7cThanks @pauldambra! - feat: addsession_recording.attributeFilteroption that passes an attribute allowlist through to the native MutationObserver, so mutations to unlisted attributes (e.g. animation-driven inlinestylechurn) never cost recording CPU (port of upstream rrweb #1873) (2026-07-15)
Patch Changes
- Updated dependencies [
800af7c]:- @posthog/types@1.395.0
1.400.1
Patch Changes
- #4090
6dd8827Thanks @lucasheriques! - chore: survey seen-key and repeat-activation helpers now live in @posthog/core, shared by the web and React Native SDKs. Core's survey enums are now const-object literal unions (matching the web SDK's existing pattern), so the same values type-check across both SDKs. No behavior change. Type-level note: enum members no longer work as standalone type annotations (e.g.SurveyType.Popoveras a type); use the exported union types instead. Runtime values are unchanged. (2026-07-14) - Updated dependencies [
6dd8827]:- @posthog/core@1.41.1
1.400.0
Minor Changes
- #4101
dc2aa5bThanks @posthog! - Normalize the error tracking rate-limiter config to first-class options. The browser SDK now readsexceptionRateLimiterRefillRate/exceptionRateLimiterBucketSizeonerror_tracking, with the previous double-underscore__exceptionRateLimiterRefillRate/__exceptionRateLimiterBucketSizeoptions deprecated but still honoured as a fallback. The option shape (ExceptionRateLimiterConfig) and default-resolution logic (resolveExceptionRateLimiterConfig) now live in@posthog/coreand are shared between the browser and Node SDKs. (2026-07-14)
Patch Changes
- #4140
1eabd30Thanks @turnipdabeets! - HandlesendBeaconquota rejections instead of silently dropping events. A beacon rejected by the browser (over the page's shared ~64KiB in-flight keepalive quota) is now split in half and re-sent recursively so the batch delivers as far as the quota allows; a rejected payload that cannot be split falls back to a non-keepalive fetch and logs a warning. Previously the boolean return ofsendBeaconwas ignored and an over-quota unload batch was lost with no signal. (2026-07-14) - Updated dependencies [
dc2aa5b]:- @posthog/core@1.41.0
- @posthog/types@1.394.0
1.399.5
Patch Changes
-
#4134
ab10064Thanks @posthog! - Bound autocapture's DOM ancestor walks against abnormal host-page DOM trees.autocapturePropertiesForElementandshouldCaptureElementnow stop climbing theparentNodechain after 1000 ancestors or if they revisit a node (only possible when a page patchesparentNode, since native DOMs cannot contain cycles), instead of walking indefinitely. WhenshouldCaptureElementcannot finish checking ancestors forph-no-capture/ph-sensitive, it fails closed and reports the element as not capturable. Behavior on normal DOM trees is unchanged. (2026-07-14) -
#4141
17d956cThanks @posthog! - Log network-level fetch failures from posthog-js's own request layer (ad blocker, dropped connection, CORS, page teardown) atwarninstead oferror. The browser rejects these with a genericTypeError(Failed to fetch, Firefox'sNetworkError..., or Safari'sLoad failed); they are already caught and retried by the request queue, so they are expected noise rather than SDK errors —_fetchnow gives them the samewarntreatment as our own timeout aborts. Genuine, unexpected errors still log aterror. (2026-07-14)
1.399.4
Patch Changes
- #4139
7c339beThanks @turnipdabeets! - Encode uncompressedsendBeaconbodies as base64 form data so the beacon keeps a CORS-simple content type. Previously an uncompressed unload beacon was sent asapplication/json, which forces a CORS preflight — a preflight cannot complete while the page unloads, so on cross-origin hosts the browser silently dropped the POST and the final batch of events was lost. Compression is inactive whenever the remote config request fails (flaky network, blocked endpoint), when the config response omitssupportedCompression, or withdisable_compression: true. (2026-07-13)
1.399.3
Patch Changes
- #4133
4ebb618Thanks @mikenicholls88! - MakejsonStringifycircular-safe so event serialization never throws. Previously a captured property holding a circular value — most commonly a DOM node that retains a React fiber pointing back at the element — madeJSON.stringifythrowConverting circular structure to JSON; withcapture_exceptionsenabled that throw was recaptured as a new$exception, at times in a loop. On a throw we now fall back tosafeJsonStringifyfrom@posthog/core. The fast (non-circular) path is unchanged, and only true cycles become"[Circular]", so shared-but-acyclic references keep their real values. (2026-07-13)
1.399.2
Patch Changes
- #4118
f630394Thanks @posthog! - Fix aRangeError: Maximum call stack size exceededoriginating from the shared rrwebpatch()helper. It patches shared globals such asElement.prototype.attachShadow(shadow-dom-manager) and the DOM/canvas observers, so multiple recorder instances or repeated start/stop cycles wrap the same global more than once. Previously an out-of-order restore silently no-op'd, leaving the wrapper in the call path; repeated cycles grew the wrapper chain without bound until a real call walked a chain deep enough to overflow the stack. Wrappers now delegate through a mutable per-layer link so any layer can be torn down even when newer wrappers sit on top of it, keeping the chain bounded. Recording behavior is unchanged. This applies the same fix as #4063 (fetch/XHR) to the shared helper so every rrweb-record caller inherits the bounded-chain behavior. (2026-07-10)
1.399.1
Patch Changes
-
#4122
c915581Thanks @github-actions! - FixTypeError: handlePageUnload is not a functionthrown on page unload when a version-skewed lazy-loaded surveys chunk produces a survey manager whose prototype lackshandlePageUnload. The delegated call inPostHogSurveys.handlePageUnload()now guards the method as well as the receiver. (2026-07-09) -
#4124
562ceebThanks @posthog! - Session recording no longer crashes on startup when a CDN-loaded recorder chunk runs against an older bundled core. Calls intoSessionIdManager.on/onSessionIdare now guarded so a core without those methods degrades gracefully instead of throwing aTypeErrorduringstart(). (2026-07-09)
1.399.0
Minor Changes
-
#4115
86bb3a5Thanks @DanielVisca! - add the posthog.metrics API (count, gauge, histogram) — alphaA statsd-style pre-aggregating metrics client for the PostHog Metrics product (alpha). Samples are folded into per-series aggregates in memory (counts sum, gauges keep the last value, histograms accumulate buckets) and flushed periodically as OTLP/JSON to
/i/v1/metrics— one data point per series per flush window, no matter how many calls. No OpenTelemetry SDK setup required:posthog.metrics.count('orders_created', 1) posthog.metrics.gauge('active_connections', 42) posthog.metrics.histogram('api_latency', 187, { unit: 'ms' })Configure via
metrics: { serviceName, environment, flushIntervalMs, maxSeriesPerFlush, beforeSend, ... }. (2026-07-08)
Patch Changes
- Updated dependencies [
86bb3a5]:- @posthog/core@1.40.0
- @posthog/types@1.393.0
1.398.7
Patch Changes
-
#4113
45f17eeThanks @TueHaulund! - fix session replay leaking a shadow-root observer when a same-origin iframe is removedFollow-up to the shadow-observer iframe-teardown fix:
takeFullSnapshot'sonSerializeregisters every shadow root with the top-level document, so a root nested in a same-origin iframe was keyed to the wrong document and its observer/buffer were not disconnected when that iframe was removed (they lingered until the next full snapshot).addShadowRootnow derives the owning document from the host element, so per-document teardown matches iframe-nested roots too. (2026-07-08)
1.398.6
Patch Changes
- #4114
c75c0baThanks @hpouillot! - fix: avoid throwing when rrweb recorder cleanup cannot remove a listener (2026-07-08)
1.398.5
Patch Changes
- #4103
be8242aThanks @rafaeelaudibert! - Publish the code-split ESM toolbar bundle when the build emits one. The release tooling now recursively includesdist/toolbar/(with explicit JS content types for the strict-MIME ESM chunks) across the immutable, major-alias, and compatibility upload prefixes, and the workflow accepts the canonicaltoolbar.js/toolbar.csslayout. This is a no-op against today's single-file build. (2026-07-08)
1.398.4
Patch Changes
-
#4104
ec5e401Thanks @TueHaulund! - fix session recordings missing their initial full snapshot after an idle session-id rotationWhen the session id rotated while the recorder was idle, the restarted recorder's Meta and FullSnapshot were appended to the previous session's buffer and shipped under the old session id, leaving the new recording unplayable until the next periodic snapshot. The buffer now rebinds on any session-id change regardless of idle state, and as a safety net the recorder requests a full snapshot whenever an incremental is about to ship for a session that has not produced one. (2026-07-08)
1.398.3
Patch Changes
-
#4112
38bb185Thanks @TueHaulund! - fix session replay silently dropping shadow DOM mutations after an iframe teardownThe single shared ShadowDomManager observes every shadow root on the page, but MutationBuffer.reset() disconnected it. That reset fires whenever any one buffer is torn down, so an iframe being removed or navigating away disconnected every shadow-root observer page-wide. Shadow DOM content (for example a widget mounted in an open shadow root) then stopped recording until the next periodic full snapshot re-registered it. Buffer teardown now releases only its own resources; global shadow observation is reset by takeFullSnapshot and on recording stop. (2026-07-08)
1.398.2
Patch Changes
-
#4063
24aadd5Thanks @posthog! - Fix aRangeError: Maximum call stack size exceededthat could originate from the sharedpatch()fetch/XHR wrapper. posthog-js wrapswindow.fetchin two independent places (tracing headers and session-recording network capture), so their restores routinely ran out of order. Previously an out-of-order restore silently no-op'd, leaving the wrapper in the call path; repeated start/stop cycles grew the wrapper chain without bound until a realfetchwalked a chain deep enough to overflow the stack. Wrappers now delegate through a mutable link so any layer can be torn down even when newer wrappers sit on top of it, keeping the chain bounded. Header-injection and network-capture behavior is unchanged. (2026-07-07) -
#4100
e250a24Thanks @marandaneto! - Stop adding the gzip compression query parameter to browser SDK requests. (2026-07-07) -
#4083
f07e241Thanks @posthog! - fix(replay): harden session-replay network capture so instrumentation that throws (e.g.new Request()rejecting a URL/method) degrades gracefully and never breaks or misattributes the host application's ownxhr.open()/fetch()calls (2026-07-07)
1.398.1
Patch Changes
- #4096
5013ab6Thanks @marandaneto! - Stop sending the deprecatedverquery parameter to capture and session recording endpoints. (2026-07-07)
1.398.0
Minor Changes
- #4070
ef119bfThanks @posthog! - Add adisableAutofocussurvey appearance option. When set, open-text survey questions no longer steal focus when they render, which is useful for embedded (inline) surveys that shouldn't grab the caret or scroll the page on load. Defaults tofalse, preserving the existing autofocus behavior. (2026-07-06)
1.397.0
Minor Changes
- #4089
cc340dbThanks @bs1180! - feat(web): add aposthog-js/customizationssubpath entry point exposing the optional customizations (setAllPersonProfilePropertiesAsPersonPropertiesForFlags, thebefore-sendsampling helpers, and the redux/kea loggers) as a proper ES module with bundled types, replacing the internalposthog-js/lib/src/customizationsdeep import. Also fixes the TypeScript definitions sosetAllPersonProfilePropertiesAsPersonPropertiesForFlagsaccepts the instance passed to theloadedcallback (the documented usage), and theloadedcallback's instance type now includesconfig. (2026-07-06)
1.396.9
Patch Changes
- #4077
2595440Thanks @pauldambra! - fix(web): stop retrying log batches forever when requests die before an HTTP response (status 0, e.g. an ad blocker) — after 3 consecutive such failures while the browser reports itself online, the logs pipeline stops sending and drops batches instead of buffering and retrying for the life of the page; theonlineevent reopens it, and genuine offline periods still queue for the reconnect flush (2026-07-06)
1.396.8
Patch Changes
- #4062
2af0026Thanks @posthog! - fix(web): prevent an infinite-recursion stack overflow in the logs console capture. The console wrapper's own capture path can emit internal debug lines through PostHog's logger, which wrote back to the wrapped console and re-entered capture until the stack blew (RangeError: Maximum call stack size exceeded). The wrapper now exposes the original console method via__rrweb_original__(so the internal logger bypasses it) and guards against re-entrancy from any code that logs mid-capture. (2026-07-06)
1.396.7
Patch Changes
- #4080
08cd27bThanks @marandaneto! - fix(web): stop repeatedly hitting blocked feature flag and conversations polling endpoints after consecutive status-0 failures (2026-07-06)
1.396.6
Patch Changes
-
#4053
45d1b36Thanks @posthog! - feat(web): add a gracefulshutdown()to the browser client for parity with posthog-node, so isomorphic teardown code (e.g. the Nuxt module) that callsposthog.shutdown()on the client no longer throwsTypeError: shutdown is not a function. It best-effort flushes the queued events and always resolves. (2026-07-03) -
#4054
f0657ebThanks @posthog! - fix(web): detect our own feature-flag request timeouts via atimedOutflag instead of the abort reason, so they are logged atwarn(noterror) on browsers that don't propagatecontroller.abort(reason)— keeping benign timeouts out of error tracking's console-error capture (2026-07-03) -
#4031
94a0530Thanks @posthog! - Improve survey display reliability:- posthog-js: refresh the cached
$surveysdefinitions after a short TTL (stale-while-revalidate) so server-side changes such as switching a survey from popover to API propagate to long-lived tabs without a page reload. - posthog-js: add
posthog.surveys.markSurveyAsSeen(surveyId, { iteration })so custom integrators that render surveys through their own backend can honour the "already seen" and wait-period checks. - posthog-react-native: guarantee the survey
Modalnotifies its parent on close even when iOSModal.onDismissfails to fire, so the transparent full-screen modal can no longer stay mounted intercepting touches and freezing the app. (2026-07-03)
- posthog-js: refresh the cached
-
Updated dependencies [
45d1b36]:- @posthog/types@1.392.1
1.396.5
Patch Changes
- #4050
d7cf13bThanks @turnipdabeets! - Prevent uncaughtgetComputedStylecrashes in heatmaps and autocapture when the event target is a cross-realm element (e.g. from an iframe or synthetic event) (2026-07-02) - Updated dependencies [
5e7e132]:- @posthog/core@1.39.5
1.396.4
Patch Changes
-
#4035
18e543bThanks @posthog! - fix(web): isolateonFeatureFlagscallbacks so a throwing user handler no longer breaks the remaining callback chain or gets misattributed as an SDK error (2026-07-01) -
#4039
15bcb42Thanks @github-actions! - fix(replay): measure$snapshot_bytesas UTF-8 byte length instead of UTF-16 string length, so non-ASCII session replay payloads are counted accurately against the message size limit (2026-07-01)
1.396.3
Patch Changes
- #4020
e0ad8efThanks @posthog! - FixTypeError: ....at is not a functionthrown by the bundledweb-vitalsdependency on browsers that predateArray.prototype.at()(Chrome <92, iOS Safari <15.4). The web-vitals entrypoints now install a tinyArray.prototype.atpolyfill before web-vitals runs, so web vitals capture works again on older browsers instead of crashing with an unhandled error. (2026-06-30)
1.396.2
Patch Changes
- #4003
b6261e7Thanks @marandaneto! - Include a Promise polyfill in the IE11 bundle and avoid Promise-dependent async compression paths when Promise support is unavailable. (2026-06-29)
1.396.1
Patch Changes
- #3999
cdeae17Thanks @marandaneto! - Fall back to uncompressed browser requests when gzip encoding fails. (2026-06-29)
1.396.0
Minor Changes
- #3987
74cc6bbThanks @TueHaulund! - Add aget_current_urlconfig option that overrides the URL used for client-side URL targeting — session replay URL triggers, the session replay URL blocklist, survey URL display conditions, product tour URL conditions, web experiment URL conditions, and autocapture URL allow/ignore lists. These match againstwindow.location.hrefdirectly, which does not reflect a$current_urlrewritten inbefore_send. Apps where the browser URL is not meaningful for targeting (e.g. Electron/desktop builds served from a generated host) can now return the logical URL to match against. Defaults towindow.location.hrefwhen not set. (2026-06-29)
Patch Changes
- Updated dependencies [
74cc6bb]:- @posthog/types@1.392.0
1.395.0
Minor Changes
- #3977
6200888Thanks @turnipdabeets! - AddgetAllFeatureFlags(), which returns all currently loaded feature flags as structuredFeatureFlagResults (key,enabled,variant,payload). It is a synchronous read of the cached flags and does not send a$feature_flag_calledevent. (2026-06-26)
Patch Changes
- Updated dependencies [
6200888]:- @posthog/core@1.38.0
1.393.6
Patch Changes
- #3965
6ef9179Thanks @marandaneto! - Handle request serialization errors without throwing or blocking queued requests. (2026-06-26)
1.393.5
Patch Changes
- #3960
619d318Thanks @marandaneto! - Improve console log capture performance for truncated large objects. (2026-06-25)
1.393.4
Patch Changes
- #3942
c9c8925Thanks @hpouillot! - Fix browser console log capture when session activity timestamps are missing and refresh session attributes for each log. (2026-06-24) - Updated dependencies [
c9c8925]:- @posthog/core@1.37.2
1.393.1
Patch Changes
- #3919
99bad9cThanks @pauldambra! - Session replay network capture: add an opt-in streaming reader for request/response bodies that stops at the payload size limit instead of buffering the whole body and then discarding it — bounding memory and pre-request latency when a body is very large. It reads only a clone of the body, so it never consumes the stream the page itself reads, and always resolves (never rejects) into the page'sfetch. Off by default; enabled fordefaults: '2026-06-25'and settable directly viasession_recording.streamNetworkBody. (2026-06-24) - Updated dependencies [
99bad9c]:- @posthog/types@1.391.1
1.393.0
Minor Changes
-
#3921
c28b161Thanks @marandaneto! - Adddisable_capture_url_hashesto strip URL fragments from automatically captured URLs. It is disabled by default for backwards compatibility, and enabled automatically whenconfig.defaultsis'2026-06-25'or later. Enabling it (either explicitly or via the'2026-06-25'defaults) is a breaking behavior change for SPAs that rely on URL hashes for routing or analytics, because hash-based routes will be collapsed to the same URL without the fragment in fields such as$current_url,$initial_current_url,$session_entry_url, autocapture$elements[*].attr__href,$external_click_url, replayhrefURLs, heatmaps, web vitals$current_url, logsurl.full, conversationscurrent_url/request_url, or Next.js Pages Router$pageview$current_url.If you only want to capture some hashes, leave hash capture enabled and use
before_sendto remove or redact sensitive hash values before events are sent. (2026-06-23)
Patch Changes
- Updated dependencies [
c28b161]:- @posthog/core@1.36.0
- @posthog/types@1.391.0
1.392.0
Minor Changes
-
#3895
ce528edThanks @turnipdabeets! - Console log auto-capture (logs: { captureConsoleLogs: true }) now flows through the same pipeline asposthog.captureLog(),posthog.logger.*, and PostHog's other SDKs, instead of OpenTelemetry. As a result:- the bundled OpenTelemetry dependencies are removed, shrinking the lazily-loaded logs chunk
- auto-captured console logs now run through
logs.beforeSend(the same hook ascaptureLog/logger.*), so you can redact or drop sensitive console output before it's sent. To treat console logs differently from manual logs, branch on the record'slog.sourceattribute: auto-captured console logs set it toconsole.<method>(e.g.console.error), while manualcaptureLog/logger.*logs leave it unset - console logs now link to the person's profile: they carry the person id as
posthogDistinctId, the attribute PostHog uses to associate logs with a person (docs). The old path useddistinct_id, which isn't used for person linking by default, so console logs previously didn't appear on person profiles unless you'd configured a custom key.
Console logs keep their
posthog-browser-logsservice.name, theirconsoleinstrumentation scope, and theirlog.source: console.<level>attribute.As part of moving onto the shared pipeline, console records now use PostHog's standard log field names — the same ones programmatic web logs and other SDKs use, and the ones the Logs UI surfaces. For the fields below the values are unchanged — only the attribute names/locations differ:
distinct_id→posthogDistinctId(record attribute)location.href→url.full(record attribute; same value — the page URL)session.id(resource attribute) →sessionId(record attribute) — renamed and movedhostandwindow.idmove from resource attributes to record attributes (names unchanged)- records also now carry the standard SDK context shared by other logs, including
feature_flags
For most projects this needs no action — these are already the canonical log fields. The only thing to update is a saved Logs query or dashboard built specifically on an old console attribute name, for example:
attributes.distinct_id→attributes.posthogDistinctIdattributes.location.href→attributes.url.fullresource.attributes.session.id→attributes.sessionIdresource.attributes.host/resource.attributes.window.id→attributes.host/attributes.window.id(2026-06-22)
Patch Changes
- Updated dependencies [
ce528ed]:- @posthog/core@1.35.4
1.391.9
Patch Changes
- #3922
26aa9baThanks @posthog! - Exception autocapture: posthog-js's own fetch timeout now aborts with an explicit, descriptive reason (PostHog request timed out after <n>ms) instead of a reason-lessDOMException: AbortError: signal is aborted without reason. This keepsname === 'AbortError'so existing timeout handling (e.g. feature flag timeout detection) is unchanged, but makes our own timeouts identifiable and stops them being re-captured as noise by console-error exception autocapture. (2026-06-22)
1.391.8
Patch Changes
- #3908
1fce04fThanks @marandaneto! - Apply CSP stylesheet preparation hook to Product Tours styles. (2026-06-22)
1.391.7
Patch Changes
- #3914
dac4edbThanks @pauldambra! - Session replay network capture: redact credential-bearing headers on both request and response (previously only request), and match credential-shaped custom header names by substring (e.g.x-gist-encoded-user-token) in addition to the exact deny list - avoiding accidental capture of tokens/cookies in recordings. (2026-06-22)
1.391.6
Patch Changes
-
#3901
049eeb6Thanks @marandaneto! - Stop adding the unusedbeaconquery parameter to browser SDK sendBeacon requests. (2026-06-22) -
#3900
3ee8667Thanks @marandaneto! - Stop adding the unusedipquery parameter to browser SDK requests. (2026-06-22)
1.391.5
Patch Changes
- #3915
beaccc3Thanks @pauldambra! - Session replay: apply the existing base64 image size cap (maxBase64ImageLength) to SVG<image>elements withdata:URIs on bothhrefandxlink:href. Previously the cap only covered<img>elements, so large inline data URIs inside SVGs were recorded in full - this also covers them in mutations, replacing oversized ones with the striped placeholder. (2026-06-22)
1.391.4
Patch Changes
- #3913
ee9f2a8Thanks @pauldambra! - Session replay network capture: expand the default payload host deny list to skip third-party analytics, RUM, and session-replay telemetry whose payloads have no replay value - Datadog, Segment, RudderStack, Amplitude, Mixpanel, Hotjar (both.comand.io), and FullStory. Also covers both Google Analytics beacon hosts (google-analytics.com, plusanalytics.google.comwhich gtag uses when Google Signals is enabled) and widens New Relic tonr-data.net. (2026-06-22)
1.391.3
Patch Changes
-
#3909
ab4a220Thanks @marandaneto! - Avoidstyle-src-attrCSP violations when diffing rrweb style mutations. (2026-06-22) -
#3912
78ac40cThanks @pauldambra! - Session replay network capture: never record binary/asset response or request bodies (image, video, audio, font, octet-stream, pdf, zip, wasm) even whenrecordBodyis enabled - they bloat recordings, duplicate what the replay already shows, and the body is no longer read. (2026-06-22)
1.391.2
Patch Changes
- #3903
6b21f77Thanks @marandaneto! - Validate custom event UUID overrides and generate new UUIDs when invalid. (2026-06-19) - Updated dependencies [
6b21f77]:- @posthog/core@1.35.3
- @posthog/types@1.390.2
1.391.1
Patch Changes
-
#3899
d090a7cThanks @lucasheriques! - Surveys: re-check eligibility when a popover's display delay elapses, instead of only re-checking the URL.A survey with a display delay could be queued while a visitor was still anonymous (the targeting flag passed for the anonymous profile), and then displayed after the delay even though
identify()had reloaded feature flags and the survey's internal targeting flag was now false for the identified profile (e.g. a "show once per user" survey the person had already dismissed). The delayed display now re-runs the full display predicate (eligibility, URL/device/selector conditions, event/action trigger, and feature flags) before rendering, so a survey that became ineligible during the delay is no longer shown. Pending delayed surveys are also cancelled promptly when a later evaluation cycle finds them ineligible. (2026-06-19)
1.391.0
Minor Changes
-
#3885
5392a55Thanks @pauldambra! - feat(replay): capture canvas at reduced resolutionAdds
session_recording.canvasCapture.resolutionScale- a(0, 1]fraction of the canvas display size to capture replay frames at. The captured bitmap is downscaled (pixel-area savings are quadratic) while the canvas's true display size is still recorded, so playback stretches the smaller frame back to the correct dimensions and aspect ratio - only sharpness drops, never layout. It defaults to1(full resolution, matching today's behaviour), and the latestdefaultsbundle (2026-05-30) opts new installs into0.6.The canvas's true display size travels with each frame through the encode worker (as required message fields), so the encoded reply is always drawn back to the correct dimensions — no per-canvas state is retained on the main thread, and downscaling can never mislabel a canvas's dimensions. At full resolution the captured pixels are unchanged (the quality resampling hint is only applied when actually downscaling); the emitted
drawImagenow always uses the explicit destination-size form, which is pixel-equivalent on replay.Mechanically,
@posthog/rrweb's canvas FPS-snapshot observer takes an optionalcanvasResolutionScalerecord option and downscales each captured frame accordingly. (2026-06-19)
Patch Changes
- Updated dependencies [
5392a55]:- @posthog/types@1.390.1
1.390.2
Patch Changes
-
#3868
a5dd54aThanks @pauldambra! - fix(replay): scope the session-recording flushed-size tracker to the session$sdk_debug_replay_flushed_sizewas stored as a single device-global value in persistence and only reset on an in-page session rotation, so it leaked across page loads and tabs and over-counted on returning visitors. The tracker now keys the running total to the current session id, so a new session starts from zero and a fresh load reading an ongoing session sees the correct total.The internal persistence key backing this counter (
$sess_rec_flush_size) was also unintentionally attached to every captured event as a super-property; it is now marked hidden so it no longer ships on events. The value remains available on session-replay debug events as$sdk_debug_replay_flushed_size. (2026-06-17)
1.390.1
Patch Changes
-
#3784
e25e629Thanks @lucasheriques! - Surveys: event-triggered surveys are now scoped to the page load the event fired in, and only persist across a page reload once they have actually been shown.Previously an event armed a survey by writing it to localStorage, where it stayed until shown. Because the activation survived reloads and the URL condition was only checked at display time, a survey armed by an exit-intent event (which fires as the user is leaving or reloading) could surface on a later page load with no event behind it. Activations now live in memory until the survey is shown, so an armed-but-unshown survey no longer reappears after a reload.
Once a survey is shown it is promoted to persistence, so a non-repeatable survey survives a reload and re-displays until the user dismisses or answers it (instead of vanishing if they reload before interacting). Repeatable surveys (
schedule: 'always'or "Show every time the event is captured") are still consumed when shown, so each captured trigger shows them once. Product tours follow the same model. Cross-page deferral (arm on one full page load, display on a later one) is no longer supported via event triggers; use audience targeting for that. (2026-06-17)
1.390.0
Minor Changes
-
#3869
81b79fbThanks @turnipdabeets! - Add abeforeSendoption to the logs config, so you can inspect, redact, or drop log records before they're sent:posthog.init('<token>', { logs: { beforeSend: (log) => { // return null to drop the log, or return the (optionally modified) log to keep it if (log.body.includes('password')) { return null } return log }, }, })beforeSendaccepts a single function or an array of functions (applied left to right); returningnullfrom any of them drops the record. It runs for logs sent via bothposthog.captureLog()andposthog.logger.*. (2026-06-17)
Patch Changes
- Updated dependencies [
81b79fb]:- @posthog/types@1.390.0
1.389.1
Patch Changes
- #3875
43b4137Thanks @marandaneto! - Limit retries for transport failures without an HTTP response. (2026-06-17)
1.389.0
Minor Changes
- #3865
b469830Thanks @turnipdabeets! - The browser's programmatic logs API (posthog.captureLog()/posthog.logger.*) now runs through the shared@posthog/corelogs pipeline that React Native already uses — no change to the public API or existing behavior. Log delivery is more resilient as a result: oversized batches are split automatically, failed sends retry with exponential backoff, and delivery resumes when the browser comes back online. (2026-06-17)
Patch Changes
- Updated dependencies [
b469830]:- @posthog/core@1.35.0
- @posthog/types@1.389.0
1.388.2
Patch Changes
- #3870
5edfee1Thanks @turnipdabeets! - FixupdateFlags(flags, payloads, { merge: true })baking an active feature flag override into the stored flags. The merge now seeds from the raw stored flags rather than the override-applied values, so clearing the override afterwards correctly restores the original flag. (2026-06-17)
1.388.1
Patch Changes
- #3851
5c453cdThanks @marandaneto! - Apply CSP nonce preparation hooks to style and script elements appended by site apps. (2026-06-17)
1.388.0
Minor Changes
- #3863
b6bc9beThanks @marandaneto! - Add autocapture-only CSS selector opt-outs for web interactions. (2026-06-17)
Patch Changes
- Updated dependencies [
b6bc9be]:- @posthog/types@1.388.0
1.387.0
Minor Changes
- #3709
c6c163aThanks @posthog! - AddunsetPersonProperties()to remove person properties, the counterpart tosetPersonProperties(). Previously the only way to unset a person property was to hand-pass a$unsetarray inside acapture()call. (2026-06-16)
Patch Changes
-
#3756
b3ec845Thanks @archievi! - Drop the event and log a warning when abefore_sendhook removes thetokenproperty, instead of silently sending an event that ingest rejects with a 401. (2026-06-16) -
#3860
c9c7df1Thanks @marandaneto! - Add$unsetto capture options and pass it through in browser capture payloads. (2026-06-16) -
#3855
fadaa4fThanks @haacked! - Stop sending theipquery parameter on feature flag requests. The flags endpoint ignores it, and some ad blockers match/flags…ip=to block flag evaluation on any domain. Dropping it from flag requests avoids the block with no functional change. Event and session recording requests are unchanged. (2026-06-16) -
#3830
0d837f5Thanks @dustinbyrne! - Avoid reloading exception and dead-click autocapture external scripts when they are already present. (2026-06-16) -
#3853
f95a0ecThanks @TueHaulund! - Capture native Fullscreen API transitions in session replay. Entering native fullscreen (element.requestFullscreen()) is rendered by the browser via the UA:fullscreenpseudo-class with no DOM mutation, so the recorder previously captured nothing and replays showed the element at its pre-fullscreen size with drifted click coordinates. The recorder now emits a reserved custom event onfullscreenchange(standard pluswebkit/moz/MSprefixes), and the replayer re-applies fullscreen layout to the element on playback (including when scrubbing into a fullscreen region) via a reservedrr_fullscreenattribute, consistent with rrweb's existingrr_*attribute namespace.Known limitation: fullscreen of an element inside a same-origin iframe is recorded against the
<iframe>element rather than the inner element, so replay pins the iframe. (2026-06-16) -
Updated dependencies [
b3ec845,c9c7df1,c6c163a]:- @posthog/core@1.33.0
- @posthog/types@1.387.0
1.386.8
Patch Changes
- #3838
3094f73Thanks @TueHaulund! - fix(replay): discard the prior session's buffer when start() bails out a pending stop(). On a stopSessionRecording() → reset() → identify(newUser) → startSessionRecording() sequence, stopSessionRecording() takes the async compression-drain path, deferring its buffer flush and teardown. start() correctly invalidates that pending cleanup so the new recorder survives, but it left the stopped session's snapshot buffer in place. The re-entrant session-id restart then flushed those previous-user snapshots under the OLD session id, producing a mixed-distinct_id session that server-sideany(distinct_id)attribution resolves to the wrong person — recordings showing the previous user's identity. start() now clears that stale buffer alongside invalidating the compression queue, matching the drop-trailing-data trade-off the bailed-out stop() path already accepts. (2026-06-15)
1.386.7
Patch Changes
-
#3837
29bf8e3Thanks @marandaneto! - Add missing bugs metadata to package manifests. (2026-06-15) -
#3832
d3a9462Thanks @archievi! - Surveys: guard the remaining unprotectedlocalStorageaccesses (reset()and thelastSeenSurveyDatewrite) so aSecurityErrorin cross-origin iframes is swallowed instead of bubbling up to user monitoring. (2026-06-15) -
Updated dependencies [
29bf8e3]:- @posthog/core@1.32.4
- @posthog/types@1.386.4
1.386.6
Patch Changes
-
#3804
a27b163Thanks @pauldambra! - fix(product-tours): drop the cached tours blob when product tours is not enabledTours fetched while product tours was enabled are cached under
ph_product_toursin the main persistence blob. Once product tours is disabled (remote config or thedisable_product_toursoption) that cache was never cleaned up, so a potentially large stale blob kept riding on every persistence write — and on every cross-tabstorageevent those writes broadcast.onRemoteConfignow clears the cached tours whenever product tours resolves to disabled; they are re-fetched if it is ever re-enabled. (2026-06-11)
1.386.5
Patch Changes
- #3801
bd06ac7Thanks @ksvat! - fix(replay): prevent silent recorder teardown on session-id rotation. When the session id rotates during active rrweb capture,_updateWindowAndSessionIdscallsstop()then synchronouslystart('session_id_changed'). Ifstop()took the_stopAfterCompressionQueueDrainspath (which fires whenever the compression queue is non-empty — common during steady recording), its async cleanup would later resolve and call_teardown()against the freshly-started recorder, stopping rrweb, removing event listeners, and emptying the V2 trigger-group matchers. From that point on, the recorder'sstatusgetter kept reportingactive/sampled(the_strategyreference was still set), but rrweb was no longer producing events, no listeners were registered, and no$snapshotdata reached the server — the session looked recording-eligible from event metadata yet produced no replay.start()now invalidates the compression-queue state (generation bump plus reset of the stop-in-progress flag and queued-event count), so any pending cleanup from a priorstop()bails at its existing generation check and a laterstop()of the new recorder is not mistaken for the old in-progress one. Affects long-running tabs that rotate session id mid-use (idle timeout, session-past-max-length, orposthog.reset()). (2026-06-11)
1.386.4
Patch Changes
- #3767
fdc07f3Thanks @arnohillen! - replay: jump scrolls instantly when seeking past pages that usescroll-behavior: smooth. During fast-forward the replayer applied scrolls withbehavior: 'auto', which inherits the page's CSSscroll-behavior— so on sites that setscroll-behavior: smooth(e.g. Silk bottom sheets/modals) a seeked scroll animated from 0 instead of jumping, leaving scroll-revealed content (the open sheet) out of view and showing only the backdrop until the animation caught up. Sync scrolls now usebehavior: 'instant', matching the method's stated intent that smooth scrolling be disabled while fast-forwarding. Full snapshot rebuilds apply their initial offset withbehavior: 'instant'too, so the document-level scroll doesn't animate either. (2026-06-11)
1.386.3
Patch Changes
-
#3760
5ddfd44Thanks @benben! - fix(conversations): re-attach the support widget after SPA navigations that replacedocument.body(e.g. Turbo Drive), so the widget no longer disappears until a full page reload (2026-06-11) -
#3690
dbf2377Thanks @pauldambra! - fix(sessionid): keep the session id stable across tabsA session now rotates only when every tab has been idle past the timeout, rather than whenever a single background tab decides it is idle. On the active event path an idle tab re-reads the session id from storage before rotating: if a sibling tab kept the session alive it does not rotate, and if a sibling already rotated it adopts that id instead of minting a new one. This removes spurious cross-tab session fragmentation (inflated session counts, truncated session durations, split replays). When a sibling session is adopted,
onSessionIdhandlers fire withchangeReason.crossTabAdoption: trueso session recording, pageview state, and session-scoped properties follow the new session. Whenpersistence_save_debounce_ms > 0(the2026-05-30default) the refresh reads only the session-id key so it cannot clobber a sibling's write.Note: projects with significant multi-tab usage will see fewer but longer sessions after upgrading — this is a correction of previously over-counted sessions, not a traffic change. (2026-06-11)
-
#3795
21441a8Thanks @pauldambra! - fix(persistence): stop per-request metadata rewriting the split-storage entries on every load$feature_flag_evaluated_at,$feature_flag_request_id, and$surveys_loaded_atchange on every/flags(or/surveys) load even when the flag and survey content is unchanged. Withsplit_storageenabled that made the multi-hundred-KB__flags/__surveyslocalStorage entries dirty on every SPA navigation, re-broadcasting the full payload to every open same-origin tab via cross-tabstorageevents — the exact pressure the split exists to remove. These keys are now marked volatile: a value-only change neither dirties the group nor alters its fingerprint, so the write is skipped and the freshest value rides along on the next real content write. Adding or deleting a volatile key still writes through (presence is fingerprinted, the moving value is not), and the in-memory value is always current — only the on-disk copy may lag until the next content change. (2026-06-11) -
Updated dependencies [
dbf2377]:- @posthog/types@1.386.3
- @posthog/core@1.32.3
1.386.1
Patch Changes
-
#3780
93e0461Thanks @dustinbyrne! - Fix stale sampled-in session replay decisions after the configured replay sample rate changes. (2026-06-10) -
#3788
6da86d0Thanks @TueHaulund! - fix(replay): never record or flush snapshots while the sampling decision is missingWhen the stored sampling decision was wiped while the recorder was running (e.g. by
posthog.reset()), the undecided session reported anactivestatus and could leak short junk recordings from sessions that then decided not to record. Sampling decisions are now persisted tagged with the session id they were made for ('!' + sessionIdwhen sampled out), are re-made on every session id change regardless of config availability, and a buffer is never flushed without a decision when sampling is configured. Because the decision is a deterministic hash of the session id, re-deciding never flips the outcome for the same session. This also stops a stalefalsedecision from a previous session being inherited by a new session, which chronically under-recorded returning visitors. (2026-06-10) -
Updated dependencies []:
- @posthog/types@1.386.1
- @posthog/core@1.32.1
1.386.0
Minor Changes
-
#3634
612f97aThanks @lucasheriques! - feat(surveys): add opt-inappearance.allowGoBackfor multi-question surveys, and make button labels translatableRenders a "Back" button on web surveys after the first question. Default is off — existing surveys are unchanged. Uses a visited-index history stack so back-navigation respects branching paths (
response_based,specific_question), and abandoned-branch responses are pruned before submission so analytics aren't polluted. Returning to a question pre-fills the prior answer.appearance.backButtonTextoverrides the default label. The button uses the survey's text color so it stays readable on any background, and it also shows in survey previews.Also adds
submitButtonTextandbackButtonTextto survey-level translations, so both the submit and back button labels can be localized viaappearancetranslations (previously only the per-question button text was translatable). (2026-06-10)
Patch Changes
- Updated dependencies [
612f97a]:- @posthog/core@1.32.0
- @posthog/types@1.386.0
1.385.0
Minor Changes
- #3777
f601c49Thanks @dustinbyrne! - Promote external dependency script versioning to supportedstrict_script_versioningandasset_hostconfig options. (2026-06-10)
Patch Changes
-
#3753
c11794dThanks @dustinbyrne! - Reload feature flags by default when resetting person properties for flags. (2026-06-10) -
#3742
23b2af1Thanks @arnohillen! - record: capture resting scroll offset onscrollendwhen a reveal scroll clamps to 0 before its target is scrollable (e.g. Silk sheets). Deduped againstscrollso normal gestures don't double event volume. (2026-06-10) -
Updated dependencies [
c11794d,f601c49]:- @posthog/types@1.385.0
- @posthog/core@1.31.4
1.384.3
Patch Changes
- #3791
2d21adaThanks @marandaneto! - Deprecate__preview_disable_beaconin favor ofdisable_beaconand mark__preview_disable_xhr_credentialsas a no-op. (2026-06-10) - Updated dependencies [
2d21ada]:- @posthog/types@1.384.3
- @posthog/core@1.31.3
1.384.2
Patch Changes
- #3789
d9462b3Thanks @marandaneto! - Deprecate__preview_eager_load_replayas a no-op now that session replay lazy loading is the default. (2026-06-10) - Updated dependencies [
d9462b3]:- @posthog/types@1.384.2
- @posthog/core@1.31.2
1.384.1
Patch Changes
- #3787
0e22d77Thanks @TueHaulund! - replayer: stop corrupting recordings when events are added behind the playhead.addEvent()used to apply any event older than the playback baseline synchronously onto the current DOM — correct for live-mode catch-up, but wrong for on-demand playback where snapshot chunks can finish loading after the user has seeked ahead. Applying those past mutations onto a DOM at a different position made theirremovesfail mirror lookups, andapplyMutationthen deleted the failed entries from the event objects themselves, so every later seek rebuilt from corrupted data (DOM nodes accumulating, e.g. duplicated text) and exports serialized the stripped events. Past events are now only applied synchronously in live mode (otherwise they are just inserted for the next seek to pick up), andapplyMutationfilters removes into a local copy instead of mutating the event data. (2026-06-10) - Updated dependencies []:
- @posthog/types@1.384.1
- @posthog/core@1.31.1
1.384.0
Minor Changes
-
#3782
0c2acb9Thanks @pauldambra! - Detect the Google Search App (GSA) as its own$browservalue (Google Search App) via the cross-platformGSA/UA marker, instead of reporting the embedded webview as Mobile Safari (iOS) or Chrome (Android). Gated behind the newdetect_google_search_appconfig option, which the2026-05-30config defaults opt into automatically — left off otherwise to keep existing browser attribution backwards-compatible.Note:
$browser_versionforGoogle Search Appis not comparable across platforms — iOS yields a version like284.0(fromGSA/284.0.564099828) while Android yields a version like14.21(fromGSA/14.21.20.28.arm64), since Google maintains separate versioning schemes for the two apps. Avoid building cross-platform version dashboards on$browser_versionfor this browser. (2026-06-10)
Patch Changes
- Updated dependencies [
0c2acb9]:- @posthog/core@1.31.0
- @posthog/types@1.384.0
1.383.3
Patch Changes
- #3776
783ba46Thanks @marandaneto! - Deprecate the no-op__preview_flags_v2browser SDK config option. The SDK already uses the/flags/?v=2endpoint by default. (2026-06-09) - Updated dependencies [
783ba46]:- @posthog/types@1.383.3
- @posthog/core@1.30.14
1.383.2
Patch Changes
- #3748
7820929Thanks @marandaneto! - Reduce duplicate internal code found by dry4ts. (2026-06-09) - Updated dependencies []:
- @posthog/types@1.383.2
- @posthog/core@1.30.13
1.383.1
Patch Changes
- #3770
e481b0cThanks @dustinbyrne! - Respectcapture_pageview: falsewhen opting out in cookielesson_rejectmode. (2026-06-08) - Updated dependencies []:
- @posthog/types@1.383.1
- @posthog/core@1.30.12
1.383.0
Minor Changes
-
#3771
227c9b0Thanks @dustinbyrne! - feat(persistence): addsplit_storageconfig option to store the feature-flag config cluster in its own localStorage entry (<name>__flags) instead of the single main persistence blob. This payload is large and changes rarely, so keeping it out of the main blob stops it riding on every high-frequency main-blob write and broadcasting on cross-tabstorageevents. Reads are unchanged: on load the entry is merged back into the in-memory props, and the old main-blob location is read once and migrated forward so upgrades never miss a cached flag. The split only applies when persistence resolves tolocalStorage/localStorage+cookie(it is pointless formemory/sessionStorageand impossible forcookie), andreset()/ opt-out wipe every entry. Defaults tofalsefor backwards compatibility; the new2026-05-30config default opts in automatically. (2026-06-08) -
#3727
393f9e2Thanks @pauldambra! - feat(surveys): extendsplit_storageto also move the survey config ($surveys) out of the main persistence blob into its own<name>__surveyslocalStorage entry, on top of the feature-flag split. Surveys now stamp a$surveys_loaded_atfreshness timestamp on every/surveysload — the survey analogue of$feature_flag_evaluated_at— so a stale__surveysentry can no longer win over a fresher survey payload written back into the main blob by a gate-off / older-SDK tab. With no timestamp on either side (migration leftover) the group entry still wins, so the migration path is unchanged. Same backend andreset()/ opt-out semantics as the flag split. (2026-06-08)
Patch Changes
1.382.0
Minor Changes
-
#3749
9877710Thanks @pauldambra! - Stop classifying intentional repeated clicks as rageclicks. From the2026-05-30config defaults, rageclick detection now ignores:- text-editing surfaces (
textarea, text-likeinputs, andcontenteditableelements), where rapid clicks are double/triple-click text selection rather than rage (rageclick.ignore_text_selection) +/-stepper buttons, added to the defaultcontent_ignorelist
Symbol-only keywords in
content_ignorelist(e.g.+,-,>,<) now match the element's text exactly instead of as a substring, so labels likesign-up,5 > 3, orC++are no longer treated as repeatedly-clicked controls. The heatmaps rageclick marker now applies the same suppression as the$rageclickevent.A partial
rageclickconfig object is now merged with the date-gated defaults instead of replacing them, so e.g.rageclick: { threshold_px: 50 }keeps the defaultcontent_ignorelist/ignore_text_selection. Pass an explicit value (e.g.content_ignorelist: false) to override a specific default, or a boolean to opt out entirely.Behaviour change for existing
content_ignorelist: trueusers (available since2025-11-30): the default list already includes>and<. After this release, buttons whose text contains>or<but is not exactly that symbol (e.g.Learn more >,< Back,home > settings) will no longer be suppressed. Bare>and<buttons remain suppressed. This is the intended fix, but if you rely on the old substring behaviour for those keywords, replacecontent_ignorelist: truewith an explicit array listing the exact terms you want to suppress. (2026-06-06) - text-editing surfaces (
Patch Changes
- Updated dependencies []:
- @posthog/types@1.382.0
- @posthog/core@1.30.10
1.381.0
Minor Changes
- #3719
a7bd828Thanks @lricoy! - Add__preview_cookie_wins_on_conflictopt-in config to prefer cookie values over localStorage when merging persistence state inlocalStorage+cookiemode, fixing cross-subdomain identify and session disconnects. (2026-06-05)
Patch Changes
- Updated dependencies [
a7bd828]:- @posthog/types@1.381.0
- @posthog/core@1.30.9
1.380.1
Patch Changes
- #3743
ced0039Thanks @robbie-c! - fix(surveys): stop the survey CSS from using:has(.survey-question:empty), which crashes some WebKit builds during text-node style invalidation while a survey renders. The empty-header margin tweak now keys off a JS-setquestion-header--emptyclass and a sibling selector instead. (2026-06-05) - Updated dependencies []:
- @posthog/types@1.380.1
- @posthog/core@1.30.8
1.380.0
Minor Changes
- #3715
2387084Thanks @dustinbyrne! - Promote browser tracing header configuration to the publictracing_headersoption while keepingaddTracingHeadersand__add_tracing_headersas deprecated aliases. (2026-06-04)
Patch Changes
- #3715
2387084Thanks @dustinbyrne! - When using tracing headers,X-POSTHOG-DISTINCT-IDis read at request time instead of when fetch/XHR is patched, ensuring it reflects bootstrap, identify, reset, and other identity changes. (2026-06-04) - Updated dependencies [
2387084]:- @posthog/types@1.380.0
- @posthog/core@1.30.7
1.379.3
Patch Changes
1.379.2
Patch Changes
- #3736
374962aThanks @arnohillen! - replay: re-apply scroll positions after fast-forward/seek. Scrolls applied mid-catch-up could clamp to 0 when the target wasn't scrollable yet (e.g. scroll-revealed sheets/modals whose content sits below the fold), leaving the content scrolled out of view on replay. The last scroll per node is now re-applied in the flush stage once layout has settled.posthog-jsis bumped too so the rebuilt bundle containing the fix is published. (2026-06-03) - Updated dependencies []:
- @posthog/types@1.379.2
- @posthog/core@1.30.5
1.379.1
Patch Changes
-
#3570
4a27cedThanks @gruessi! - fix(record): release iframe documents and observers on iframe removal — same-origin iframes mounted and unmounted while session recording is active no longer leak theirDocument, every node serialized into the mirror, or oneMutationObserverper mount. Closes eight retainer chains: load-listener disposers, named pagehide handlers, therecordCrossOriginIframescleanup gate (now applied to same-origin too), capturedDocument/Windowsets that surviveiframe.srcswap-to-about:blankbefore removal, and the globalmutationBuffers[]/handlers[]arrays which previously accumulated forever. Validated end-to-end: a host page that mounts/unmounts 5 blob-URL iframes every 2s for 110s went from +118 MB / +390 leakedHTMLDocuments to ~0 MB / 0. (2026-06-03) -
#3717
1688b38Thanks @turnipdabeets! - Move the OpenTelemetry logs dependencies todevDependencies. They are only used to build the CDN-servedlogsextension chunk, which inlines them, so consumers no longer install the transitiveprotobufjs(whoseeval("require")trippedunsafe-evalContent Security Policies).If you imported
@opentelemetry/*directly while relying on it being hoisted fromposthog-js, add it to your own dependencies. (2026-06-03) -
Updated dependencies []:
- @posthog/types@1.379.1
- @posthog/core@1.30.4
1.379.0
Minor Changes
- #3722
c487070Thanks @marandaneto! - Add$sdk_dist_channelevent property for browser SDKnpmandcdndistribution channels. (2026-06-02)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.379.0
- @posthog/core@1.30.3
1.378.1
Patch Changes
- #3706
8fcf40dThanks @dustinbyrne! - fix(browser): avoid exposing internally-created Request bodies to downstream fetch wrappers in Safari. (2026-06-01) - Updated dependencies []:
- @posthog/types@1.378.1
- @posthog/core@1.30.2
1.378.0
Minor Changes
- #3688
8181354Thanks @pauldambra! - feat(persistence): addpersistence_save_debounce_msconfig option to coalesce rapid storage saves into a single write. Setting a positive value debounces writes to localStorage/cookie by that window; the in-memorypropsobject still updates synchronously so within-tab reads see the latest values immediately, and pending writes flush onbeforeunloadandpagehideso no state is lost on tab close. Cross-tabstorageevents are reduced proportionally to the debounce window. Defaults to0(no debouncing) for backwards compatibility. On pages that capture many events per second,250is a reasonable starting point. The new2026-05-30config default opts intopersistence_save_debounce_ms: 250automatically. (2026-06-01)
Patch Changes
- Updated dependencies [
8181354]:- @posthog/types@1.378.0
- @posthog/core@1.30.1
1.377.0
Minor Changes
-
#3708
3d4a76fThanks @pauldambra! - Detect Brave (desktop, Android, iOS), Vivaldi, Yandex, Naver Whale, DuckDuckGo, Pale Moon, and Waterfox so users on these browsers no longer get bucketed as Chrome or Firefox.detectBrowser/detectBrowserVersionnow accept an optional third argument,BrowserDetectionHints, with abraveflag (set whennavigator.braveexists). The browser SDK populates this automatically to catch desktop / Android Brave, which is Chromium-based and carries no UA marker. Brave on iOS is picked up purely from theBrave/UA marker — WebKit doesn't shipnavigator.brave. The original two-argument signature still works for non-DOM callers. (2026-06-01)
Patch Changes
- #3703
f3cc6faThanks @marandaneto! - Disable/no-op initialization paths instead of throwing or sending requests when PostHog project tokens are missing or blank. (2026-06-01) - Updated dependencies [
3d4a76f]:- @posthog/core@1.30.0
- @posthog/types@1.377.0
1.376.6
Patch Changes
- #3687
663e250Thanks @pauldambra! - fix(persistence): skip the storage write when the serialized props are unchanged. Callers spamsave()after every property change, and many of those changes leave the serialized payload identical (e.g. resetting a value to its current value). Writing identical bytes to localStorage still fires a cross-tabstorageevent in every same-origin tab, where Chrome allocates the payload buffer in mojo IPC even though no listener reacts. Nowsave()compares the serialized payload against the last successful write and bails out when nothing changed. (2026-05-31) - Updated dependencies []:
- @posthog/types@1.376.6
- @posthog/core@1.29.15
1.376.5
Patch Changes
- #3686
66cbc59Thanks @pauldambra! - fix(persistence): throttle session-activity timestamp writes to a 5s granularity. The in-memory value still moves at full resolution; only writes to localStorage/cookie are coalesced. Activity-timestamp-only updates within the granularity window are skipped, dropping localStorage write pressure and cross-tabstorageevent broadcasts on pages that capture many events per second. The pending in-memory value is flushed ondestroyandbeforeunloadso a tab close inside the window does not leave the persisted value up to 5s stale for sibling tabs. The flush re-reads storage first and bails out if a sibling tab has rotated the session, so the flush cannot clobber the new session with the old id/start. (2026-05-31) - Updated dependencies [
d9ad199]:- @posthog/core@1.29.14
- @posthog/types@1.376.5
1.376.4
Patch Changes
-
#3685
f59f35aThanks @ioannisj! - fix(cookieless): enable request queue when opting out inon_rejectmode. When usingcookieless_mode: "on_reject", callingopt_out_capturing()correctly switched the SDK into cookieless capturing but never enabled theRequestQueue— so batched events were enqueued but never flushed over the network. At init time the queue was not started because consent wasPENDINGandis_capturing()returnedfalse;opt_out_capturing()is the first moment capturing becomes active but was missing the_start_queue_if_opted_in()call thatopt_in_capturing()already had. (2026-05-28) -
#3692
f01cd93Thanks @ksvat! - fix(replay): take a fresh full snapshot after session ID rotates viaforcedIdleReset. Previously, when the session manager's idle enforcement timer rotated the session id, the recorder tore down rrweb and set_isIdle = 'unknown'before the new session id was observed. Neither restart path then fired (the_onSessionIdCallbackguard only restarted when_isIdle === true, and_updateWindowAndSessionIdscould not run with rrweb stopped), so the new session received only incremental mutations until a later snapshot — leaving the player stuck on "Buffering". The restart guard now also fires when rrweb isn't running. (2026-05-28) -
#3691
cc71f3fThanks @ksvat! - fix(replay): shipph-no-captureabsolute-position fix from #3678 toposthog-js. The original changeset only bumped@posthog/rrweband@posthog/rrweb-snapshot; becauseposthog-jsdepends on@posthog/rrwebviaworkspace:*, the cascade did not bumpposthog-js, so the rebuilt bundle containing the fix was not published. This changeset re-publishesposthog-jswith the fix. (2026-05-28) -
#3695
e1ff722Thanks @ksvat! - chore(replay): expose$sdk_debug_rrweb_attachedand$sdk_debug_rrweb_start_attempteddebug properties on captured events. Today the SDK already stamps several$sdk_debug_*properties (start reason, linked-flag trigger status, recording status) that report the SDK's intent to record — they all flip to "active" as soon as the state machine evaluates the configured triggers. None of them observe whether rrweb actually attached and is producing events. The new booleans close that gap:$sdk_debug_rrweb_start_attemptedis set when_startRecorder()is first entered, and$sdk_debug_rrweb_attachedreflects whether_stopRrwebis currently a non-falsy stop handle (i.e.rrwebRecord({...})returned successfully and the recorder has not been torn down). No behavior change — this only adds two booleans to the existingsdkDebugPropertieschannel, used to diagnose cases where a session reportstrigger_activated/recording_status: activebut no$snapshotdata is ever uploaded. (2026-05-28) -
Updated dependencies [
7b84b75]:- @posthog/core@1.29.13
- @posthog/types@1.376.4
1.376.3
Patch Changes
- #3649
9cac1f6Thanks @marandaneto! - Improve console log serialization performance for large objects. (2026-05-27) - Updated dependencies []:
- @posthog/types@1.376.3
- @posthog/core@1.29.12
1.376.2
Patch Changes
- #3667
cafa9ccThanks @pauldambra! - fix(replay): stop polling preload-as-style<link>elements forever. Session recorder treated<link rel="preload" as="style" href="*.css">as if it were a stylesheet and waited forlink.sheetto populate. Per spec preload links never instantiate aCSSStyleSheet, so the wait timed out, re-serialized the link, scheduled another wait, and leaked aloadlistener on every cycle — multiplying further on every realloadevent. Pages with Next.js-style CSS preloads accumulated thousands of active polling chains, saturating the main thread and freezing the tab on refocus (2026-05-26) - Updated dependencies []:
- @posthog/types@1.376.2
- @posthog/core@1.29.11
1.376.0
Minor Changes
- #3655
6e8d349Thanks @arnaudhillen! - Expose the in-repo@posthog/rrweb,@posthog/rrweb-types, and@posthog/rrweb-plugin-console-recordpackages as subpath entry points onposthog-js. Consumers can nowimport { Replayer } from 'posthog-js/rrweb',import type { eventWithTime } from 'posthog-js/rrweb-types', andimport { LogLevel } from 'posthog-js/rrweb-plugin-console-record'instead of installing the underlying rrweb packages directly. The rrweb worker sourcemap (image-bitmap-data-url-worker-*.js.map) is also shipped fromposthog-js/dist/so downstream bundlers no longer need to reach intonode_modules/@posthog/rrweb. (2026-05-22)
Patch Changes
- #3639
c806ccaThanks @marandaneto! - Use native async gzip compression for session recording events when CompressionStream is available. (2026-05-22) - Updated dependencies [
c806cca]:- @posthog/core@1.29.9
- @posthog/types@1.376.0
1.375.0
Minor Changes
- #3641
2e1d5f4Thanks @dustinbyrne! - Addflag_keysconfig to restrict browser feature flag remote evaluation to specific flag keys. (2026-05-21)
Patch Changes
- Updated dependencies [
2e1d5f4]:- @posthog/types@1.375.0
- @posthog/core@1.29.8
1.374.4
Patch Changes
-
#3638
87e2145Thanks @marandaneto! - Apply tracing headers to matching XMLHttpRequest requests (2026-05-21) -
#3646
4f87827Thanks @marandaneto! - Avoid throwing or initializing PostHogProvider when no API key or client is provided (2026-05-21) -
#3645
280832bThanks @TueHaulund! - Capture<link rel="stylesheet">URLs fromlink.sheet.hrefand trylink.sheetdirectly for inlining, so recordings survive SPAhistory.pushStatenavigations between routes of different path depths (wherelink.hrefre-resolves against a new baseURI butlink.sheet.hrefpreserves the URL the browser actually fetched).Ships the fix landed in #3635, which only bumped the internal
@posthog/rrweb-snapshotpackage — that package is bundled intoposthog-jsat build time but is not published to npm on its own, so aposthog-jsbump is needed to actually deliver the change. (2026-05-21) -
Updated dependencies []:
- @posthog/types@1.374.4
- @posthog/core@1.29.7
1.374.2
Patch Changes
-
#3550
df91995Thanks @TueHaulund! - Preserve session-recording remote config acrossposthog.reset().posthog.reset()was clearing the entire persistence store, which wiped$session_recording_remote_configalong with user state. On the next session rotation triggered by the reset,start('session_id_changed')would early-return because the remote config was missing — leaving rrweb torn down and the new session opening with no Meta + FullSnapshot until the next periodic 5-minute checkout.This affected any flow where an app calls
posthog.reset()mid-session (e.g. on sign-out / sign-in) and was particularly visible on Flutter Web recordings that depend on a fresh FullSnapshot to anchor the CanvasKit DOM. (2026-05-18) -
Updated dependencies []:
- @posthog/types@1.374.2
- @posthog/core@1.29.5
1.374.1
Patch Changes
- #3627
07a0f5fThanks @marandaneto! - Respect transport overrides passed to posthog.capture. (2026-05-18) - Updated dependencies []:
- @posthog/types@1.374.1
- @posthog/core@1.29.4
1.374.0
Minor Changes
- #3620
594ea11Thanks @pauldambra! - Dead clicks: add a.ph-no-deadclickCSS class (andcapture_dead_clicks.css_selector_ignorelistconfig option) to exclude specific elements from dead-click detection without affecting autocapture, session replay, or heatmaps. Mirrors the existing.ph-no-rageclickpattern. (2026-05-18)
Patch Changes
- #3621
3c0a09fThanks @pauldambra! - Dead clicks: a click on an<a>(or any element inside an<a>, including across shadow DOM) is no longer flagged as a dead click — the browser navigates / downloads / opens a new window and we can't observe that. Reuses autocapture's existing DOM walker for the ancestor walk. Direct clicks on<button>,<input>,<select>,<textarea>,<label>, and<form>(previously all skipped) are now eligible for dead-click detection: if their JS handler ran, the existing mutation / scroll / selection observers see the effect; if it didn't, dead-click correctly surfaces the bug. A broken<button>with no handler, or an<svg>icon inside one, will now flag — which is exactly the dead-click case we want to catch. (2026-05-18) - Updated dependencies [
594ea11]:- @posthog/types@1.374.0
- @posthog/core@1.29.3
1.373.5
Patch Changes
- #3613
221973eThanks @lucasheriques! - Surveys: submit open text questions with Cmd/Ctrl+Enter. The textarea still inserts a newline on plain Enter (native behaviour), matching the convention used by Slack, GitHub, Discord, and ChatGPT for multi-line inputs. Single-line "Other:" inputs continue to submit on plain Enter as before. (2026-05-15) - Updated dependencies []:
- @posthog/types@1.373.5
- @posthog/core@1.29.2
1.373.4
Patch Changes
- #3602
4b895bfThanks @marandaneto! - Validate gzip request bodies at the browser send boundary and fall back to JSON if the outgoing body is not gzip data. (2026-05-12) - Updated dependencies [
4b895bf]:- @posthog/core@1.29.1
- @posthog/types@1.373.4
1.373.2
Patch Changes
- #3568
223d925Thanks @marandaneto! - Validate native gzip output before sending requests and fall back when CompressionStream returns malformed data. (2026-05-11) - Updated dependencies [
223d925]:- @posthog/core@1.28.7
- @posthog/types@1.373.2
1.373.1
Patch Changes
- #3566
7d027bcThanks @dustinbyrne! - Prevent browser log capture from throwing when console arguments contain unreadable properties. (2026-05-11) - Updated dependencies []:
- @posthog/types@1.373.1
- @posthog/core@1.28.6
1.373.0
Minor Changes
- #3547
4c0c7d9Thanks @williamchong! -capture()now accepts an optionaluuidonCaptureOptions. (2026-05-11)
Patch Changes
-
#3561
3511848Thanks @marandaneto! - Handle invalid persisted session replay config JSON gracefully (2026-05-11) -
#3559
0a835faThanks @marandaneto! - Skip remote config background refreshes when no document is available. (2026-05-11) -
Updated dependencies [
4c0c7d9,0a835fa]:- @posthog/types@1.373.0
- @posthog/core@1.28.5
1.372.10
Patch Changes
-
#3544
d120042Thanks @ksvat! - fix: stop session recording before destroying sessionManager inopt_out_capturing()withcookieless_mode: "on_reject". Previously, queued/throttled rrweb events (e.g. mousemove) could fire after the sessionManager was set toundefinedand throw[SessionRecording] must be started with a valid sessionManager. Also adds a defensive early-return inonRRwebEmitso any remaining late events bail out instead of throwing. (2026-05-07) -
#3542
94a5ba0Thanks @TueHaulund! - Preserve<style>textContent when the browser's CSSOM serialization would emit empty longhands fromvar()inside a shorthand. When a stylesheet has e.g.padding: var(--p); padding-bottom: var(--pb);, browsers store the shorthand's longhands with empty token lists per the CSS Custom Properties spec, andCSSStyleRule.cssTextre-emits them aspadding-top: ; padding-right: ; padding-left: ;. The previous behavior replaced the<style>text with that corrupted output, silently dropping layout rules on replay. We now detect the empty-longhand pattern and keep the original textContent in that case. Affects users of any CSS-in-JS framework that combinesvar()with shorthands (Chakra UI v3, Panda CSS, Emotion, etc.). Same class of bug as rrweb-io/rrweb#1667. (2026-05-07) -
Updated dependencies []:
- @posthog/types@1.372.10
- @posthog/core@1.28.4
1.372.9
Patch Changes
- #3537
026e09dThanks @TueHaulund! - Pull in the canvas-manager fix from@posthog/rrweb0.0.61: skip canvas snapshots while the WebGL context is lost so transparent bitmaps don't poison the worker's fingerprint dedup map and silently kill canvas recording for the rest of the session. Also wrapsgetCanvas()in try/catch so DOM/shadow-root traversal errors can't cancel the rAF loop. See PR #3527 for context. (2026-05-05) - Updated dependencies []:
- @posthog/types@1.372.9
- @posthog/core@1.28.3
1.372.8
Patch Changes
- #3515
255b273Thanks @marandaneto! - Gate survey translation logs behind SDK debug logging to avoid production console spam. (2026-05-04) - Updated dependencies [
220cd61,255b273]:- @posthog/core@1.28.2
- @posthog/types@1.372.8
1.372.6
Patch Changes
- #3492
cf56753Thanks @lucasheriques! - Add translated survey rendering support in React Native and share survey translation logic through@posthog/core. (2026-05-01) - Updated dependencies [
cf56753,04db756]:- @posthog/core@1.28.0
- @posthog/types@1.372.6
1.372.3
Patch Changes
- #3488
5b8efc3Thanks @lucasheriques! - Add browser survey translation rendering and language tracking. (2026-04-27) - Updated dependencies []:
- @posthog/types@1.372.3
- @posthog/core@1.27.7
1.372.2
Patch Changes
- #3484
cba2570Thanks @veryayskiy! - Fix autofocus (2026-04-27) - Updated dependencies []:
- @posthog/types@1.372.2
- @posthog/core@1.27.6
1.372.1
Patch Changes
- #3464
70508dfThanks @dustinbyrne! - Avoid usingBlob.stream()for native async gzip compression to prevent SafariNotReadableErrorstream failures. (2026-04-24) - Updated dependencies [
70508df]:- @posthog/core@1.27.5
- @posthog/types@1.372.1
1.372.0
Minor Changes
- #3470
eaa1322Thanks @veryayskiy! - You cannot write to a resolve ticket. Start a new one. (2026-04-24)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.372.0
- @posthog/core@1.27.4
1.371.3
Patch Changes
- #3445
61cf83eThanks @dustinbyrne! - Fix session recording in the full no-external browser bundles (2026-04-24) - Updated dependencies [
daf028d]:- @posthog/core@1.27.2
- @posthog/types@1.371.3
1.371.2
Patch Changes
- #3453
96f19b7Thanks @turnipdabeets! - Lift OTLP log serialization helpers from posthog-js into @posthog/core so the upcoming React Native logs feature consumes the same builders. Browser gains two fixes as a side effect: NaN and ±Infinity attribute values no longer get silently dropped during JSON encoding, and the scope.version OTLP field is now populated with the SDK version (changes the server's instrumentation_scope column from "posthog-js@" to "posthog-js@"). (2026-04-23) - Updated dependencies [
96f19b7]:- @posthog/types@1.371.2
- @posthog/core@1.27.1
1.371.1
Patch Changes
- #3425
2da17e8Thanks @marandaneto! - Classify SDK-owned persistence keys with an explicit event exposure policy so new internal persistence state must be intentionally marked as event-visible, hidden, or derived. (2026-04-23) - Updated dependencies []:
- @posthog/types@1.371.1
1.371.0
Patch Changes
-
#3432
1a8b727Thanks @richardsolomou! - refactor: rename__add_tracing_headerstoaddTracingHeaders. The__prefix signalled an internal/experimental option, but the config is a public API (documented for linking LLM traces to session replays).__add_tracing_headerscontinues to work as a deprecated alias on the browser SDK.Also exposes
patchFetchForTracingHeadersfrom@posthog/coreso non-browser SDKs can reuse the implementation. (2026-04-23) -
Updated dependencies [
1a8b727]:- @posthog/core@1.27.0
- @posthog/types@1.371.0
1.370.1
Patch Changes
- #3442
6f19ce8Thanks @marandaneto! - fix(surveys): guard survey seen localStorage access (2026-04-22) - Updated dependencies []:
- @posthog/types@1.370.1
1.370.0
Minor Changes
- #3389
922a1c1Thanks @hpouillot! - Add exception steps to error tracking (aka breadcrumbs) (2026-04-22)
Patch Changes
- Updated dependencies [
922a1c1]:- @posthog/types@1.370.0
- @posthog/core@1.26.0
1.369.4
Patch Changes
- #3362
d61bce1Thanks @sampennington! - fix(cookieless): start in cookieless mode when opt_out_capturing_by_default is set (2026-04-21) - Updated dependencies []:
- @posthog/types@1.369.4
1.369.2
Patch Changes
- #3386
4a65604Thanks @dustinbyrne! - Add a preview flag for versioned browser lazy bundle asset paths. (2026-04-16) - Updated dependencies [
4a65604]:- @posthog/types@1.369.2
1.369.1
Patch Changes
-
#3393
85ae4d9Thanks @haacked! - Exclude active feature flag payloads from event properties (2026-04-16) -
#3392
00cd1ceThanks @haacked! - Fix unnecessary persisted config and activation properties (including product tours, surveys, and session recording config) added to captured events (2026-04-16) -
Updated dependencies []:
- @posthog/types@1.369.1
1.368.2
Patch Changes
- #3378
f1bea33Thanks @marandaneto! - Disable native gzip compression after a NotReadableError in the browser SDK (2026-04-14) - Updated dependencies []:
- @posthog/types@1.368.2
1.368.1
Patch Changes
- #3379
d7c71b1Thanks @dmarticus! - Fix bootstrapped feature flags being overwritten by partial /flags response whenadvanced_only_evaluate_survey_feature_flagsis enabled (2026-04-14) - Updated dependencies []:
- @posthog/types@1.368.1
1.367.0
Minor Changes
- #3242
353be9aThanks @dustinbyrne! - feat: Add support for pre-loaded remote-config (2026-04-09)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.367.0
1.366.2
Patch Changes
- #3364
575e354Thanks @lucasheriques! - Add a hover state to numeric survey rating options so they provide clearer pointer feedback before selection. (2026-04-09) - Updated dependencies []:
- @posthog/types@1.366.2
1.366.1
Patch Changes
- #3360
802bf39Thanks @jabahamondes! - Re-evaluate consent persistent store when config changes to support cross-subdomain consent sharing (2026-04-09) - Updated dependencies []:
- @posthog/types@1.366.1
1.366.0
Minor Changes
- #3305
b599672Thanks @veryayskiy! - Add customer side identification (2026-04-09)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.366.0
1.365.4
Patch Changes
- #3353
3939856Thanks @lucasheriques! - Expose the current question index on.survey-boxvia adata-question-indexattribute. This gives consumers rendering surveys via the API a reliable way to know which question is currently displayed without parsing input ids or class names — works for every question type, including link questions which render no input or rating element. (2026-04-08) - Updated dependencies []:
- @posthog/types@1.365.4
1.365.3
Patch Changes
- #3357
dbdddcaThanks @pauldambra! - Bump @posthog/rrweb packages to 0.0.56, which includes:- PostHog/posthog-rrweb#157: fix: clear mutation buffer on iframe pagehide to prevent recording corruption
- PostHog/posthog-rrweb#158: fix: skip unchanged setAttribute calls to prevent replay flicker
- PostHog/posthog-rrweb#159: fix: prevent iframe leak in untainted prototype and avoid unnecessary iframe creation
- PostHog/posthog-rrweb#163: fix: handle SecurityError in IframeManager destroy and removeIframeById
- PostHog/posthog-rrweb#166: fix: remove postcss from @posthog/rrweb-record bundle (420KB → 170KB) (2026-04-08)
- Updated dependencies []:
- @posthog/types@1.365.3
1.365.2
Patch Changes
- #3323
c387f6dThanks @pauldambra! - perf(replay): reduce memory and CPU cost of event compression by caching gzipped empty arrays and eliminating redundant JSON.stringify for size estimation (2026-04-08) - Updated dependencies [
c387f6d]:- @posthog/types@1.365.2
1.365.0
Minor Changes
- #3302
fc5589fThanks @dmarticus! - preserve $set_once semantics in local flag evaluation cache (2026-04-07)
Patch Changes
- Updated dependencies [
fc5589f]:- @posthog/core@1.25.0
- @posthog/types@1.365.0
1.364.7
Patch Changes
- #3319
b25b689Thanks @dustinbyrne! - fix: send $groupidentify for new groups even when no properties are provided (2026-04-03) - Updated dependencies []:
- @posthog/types@1.364.7
1.364.6
Patch Changes
- #3316
68cd4e5Thanks @dustinbyrne! - Fix slim bundle + extension bundles crash caused by inconsistent property mangling (2026-04-02) - Updated dependencies [
a01a3d5]:- @posthog/core@1.24.6
- @posthog/types@1.364.6
1.364.5
Patch Changes
-
#3309
197eedaThanks @marandaneto! - Extract CLI and sourcemap utilities from @posthog/core into @posthog/plugin-utils to remove cross-spawn from React Native dependencies (2026-04-01) -
#3312
c5feb5cThanks @TueHaulund! - Bump @posthog/rrweb-* to 0.0.52 — adds error recovery to the canvas FPS snapshot pipeline, preventing canvas recording from permanently stopping when createImageBitmap or the worker encounters an error (2026-04-01) -
#3315
7b944fcThanks @TueHaulund! - Bump @posthog/rrweb-* to 0.0.53 — fixes infinite recursion crash ("Maximum call stack size exceeded") when calling posthog.reset() or restarting the recorder on pages with shadow DOM elements (e.g. CometChat) (2026-04-01) -
Updated dependencies [
197eeda]:- @posthog/core@1.24.5
- @posthog/types@1.364.5
1.364.4
Patch Changes
- #3298
2365df5Thanks @TueHaulund! - fix: skip deep copy for snapshot/exception events to prevent stack overflow on deeply nested DOM trees (2026-03-31) - Updated dependencies []:
- @posthog/types@1.364.4
1.364.3
Patch Changes
- #3300
bab5f3aThanks @dustinbyrne! - Strip workspace:* references from lib/package.json after build (2026-03-31) - Updated dependencies []:
- @posthog/types@1.364.3
1.364.2
Patch Changes
- #3297
341caafThanks @marandaneto! - fix: wrap sendBeacon body in Blob to ensure Content-Type header is set (2026-03-30) - Updated dependencies [
a863914]:- @posthog/core@1.24.4
- @posthog/types@1.364.2
1.364.0
Minor Changes
- #3285
00a5079Thanks @pauldambra! - Reject the strings "undefined" and "null" in posthog.identify(). All invalid distinct IDs now log a critical console error (always visible, not debug-only). (2026-03-27)
Patch Changes
- #3286
8d34289Thanks @marandaneto! - Use async native CompressionStream for gzip compression to avoid blocking the main thread (2026-03-27) - Updated dependencies [
8d34289]:- @posthog/core@1.24.2
- @posthog/types@1.364.0
1.363.6
Patch Changes
- #3279
32edaadThanks @pauldambra! - Bump @posthog/rrweb packages to 0.0.51, which includes:- PostHog/posthog-rrweb#145: fix: handle cross-origin iframe errors during stop handler cleanup
- PostHog/posthog-rrweb#148: fix: mask textarea innerText mutations
- PostHog/posthog-rrweb#150: fix: guard WebGLRenderingContext access for iOS compatibility
- PostHog/posthog-rrweb#151: refactor: extract slimDOMDefaults into shared function
- PostHog/posthog-rrweb#152: fix: improve nested CSS rule handling
- PostHog/posthog-rrweb#153: fix: allow clearing adopted stylesheets with empty strings
- PostHog/posthog-rrweb#154: fix: prevent object reference mutation breaking remote CSS replay
- PostHog/posthog-rrweb#156: fix: catch all SecurityError variants in stop handler cleanup (2026-03-26)
- Updated dependencies []:
- @posthog/types@1.363.6
1.363.5
Patch Changes
-
#3278
c59dc90Thanks @dustinbyrne! - Add tree-shakeable ESM extension-bundles entry point for slim builds (2026-03-25) -
#3274
ba08262Thanks @pauldambra! - fix: document visibility change shoudln't capture dead click (2026-03-25) -
Updated dependencies [
ba08262]:- @posthog/types@1.363.5
1.363.3
Patch Changes
- #3253
42fbd41Thanks @marandaneto! - Reduce browser SDK bundle size by ~6.6 KB (-3.7%) through code modernization, build config tuning, string deduplication, enum-to-const conversions, and property access shorthand getters. (2026-03-23) - Updated dependencies []:
- @posthog/types@1.363.3
1.363.0
Minor Changes
- #3247
7efa558Thanks @dmarticus! - prevent silent identity switch during bootstrap and auto-identify anonymous users (2026-03-20)
Patch Changes
- #3245
1acd6fdThanks @dmarticus! - handle plain array and object forms in overrideFeatureFlags (2026-03-20) - Updated dependencies [
1acd6fd]:- @posthog/types@1.363.0
1.362.0
Minor Changes
- #3244
ff8a93eThanks @sampennington! - Fixed $set_once initial person properties (e.g. $initial_current_url) not being included with $identify calls when they had already been sent with a prior event. This ensures initial properties are reliably set when identifying users across subdomains, even if an anonymous event was captured first. (2026-03-18)
Patch Changes
- Updated dependencies [
9cd2313]:- @posthog/core@1.24.0
- @posthog/types@1.362.0
1.361.1
Patch Changes
- #3249
c265d62Thanks @marandaneto! - fix: preserve_overrideSDKInfofrom terser mangling so wrapper SDKs can call it (2026-03-18) - Updated dependencies []:
- @posthog/types@1.361.1
1.361.0
Minor Changes
-
#3201
552c018Thanks @frankh! - Add a serviceName config option to logs config (2026-03-18) -
#3240
e4a58d0Thanks @marandaneto! - Add internal_overrideSDKInfomethod to allow wrapper SDKs to override$liband$lib_versionevent properties (2026-03-18) -
#3241
fe1fd7bThanks @dustinbyrne! - feat: addadvanced_feature_flags_dedup_per_sessionconfig option to scope$feature_flag_calleddeduplication to the current session (2026-03-18)
Patch Changes
-
#3239
bf4f078Thanks @jonathanlab! - fix: debug mode not persisting across page navigations (2026-03-18) -
#3228
8773fdfThanks @TueHaulund! - fix: restart session recorder when session rotates externally while idle, preventing "Recording not found" for sessions where analytics events triggered session rotation (2026-03-18) -
Updated dependencies [
552c018,fe1fd7b]:- @posthog/types@1.361.0
1.360.2
Patch Changes
- #3236
bc30c2dThanks @dustinbyrne! - fix: Calling reset() now automatically reloads feature flags (2026-03-13) - Updated dependencies [
bc30c2d,bc30c2d]:- @posthog/core@1.23.4
- @posthog/types@1.360.2
1.360.0
Patch Changes
-
#3213
db089fdThanks @TueHaulund! - fix(replay): treat legacy configs without cache_timestamp as freshConfigs persisted by older SDK versions never include a cache_timestamp. Defaulting to 0 treats them as always stale, causing the persisted config to be cleared before start() runs — so recording never starts for customers on older core SDK versions paired with the latest CDN recorder. (2026-03-09)
-
#3207
c5a37cbThanks @dustinbyrne! - fix: PostHogFeatureFlags uses a TreeShakeabletype (2026-03-09) -
Updated dependencies [
c5a37cb]:- @posthog/types@1.360.0
1.359.1
Patch Changes
- #3204
2b0cd52Thanks @marandaneto! - chore: upgrade dompurify to 3.3.2 (2026-03-06) - Updated dependencies []:
- @posthog/types@1.359.1
1.359.0
Minor Changes
- #3166
9180726Thanks @dustinbyrne! - feat: Tree-shake feature flags (2026-03-05)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.359.0
1.358.1
Patch Changes
-
#3191
9f41d26Thanks @TueHaulund! - fix(replay): fall back to persisted config when remote config fetch failsWhen the remote config fetch failed (network error, ad blocker, CDN outage), the SDK received an empty
{}response with nosessionRecordingkey. TheonRemoteConfighandler returned early without ever setting_receivedFlags = true, leaving the recording permanently stuck inpending_configstatus for the entire page session.This removes the
_receivedFlagsgate entirely. The 1-hour TTL on persisted config (added in #3051, increased from 5 minutes) and the stale-config retry in_onScriptLoaded(added in #3093) already prevent recording from starting with outdated config. The additional gate was redundant and created a deadlock when the config fetch failed.Now when the config fetch fails,
startIfEnabledOrStop()is called and falls back to persisted config from a previous page load. If no persisted config exists (first-ever visit), recording is correctly disabled rather than silently stuck. (2026-03-04) -
#3198
9d0df0eThanks @TueHaulund! - Reduce session replay memory pressure by tracking per-event sizes in SnapshotBuffer, eliminating redundant JSON.stringify calls during buffer operations. Also bumps @posthog/rrweb to 0.0.46 which uses FNV-1a hash-based canvas frame deduplication instead of storing full base64 strings. (2026-03-04) -
Updated dependencies []:
- @posthog/types@1.358.1
1.358.0
Minor Changes
- #3165
0e08337Thanks @dustinbyrne! - feat: Tree-shake surveys, toolbar, exceptions, conversations, logs, experiments (2026-03-03)
Patch Changes
- #3164
20c1ff2Thanks @dustinbyrne! - Add Extension interface for tree-shakable extensions (2026-03-03) - Updated dependencies []:
- @posthog/types@1.358.0
1.357.0
Minor Changes
- #3169
4f885c0Thanks @marandaneto! - feat: add local sampleRate config for session recording (2026-03-02)
Patch Changes
- #3179
0dce119Thanks @TueHaulund! - Bump @posthog/rrweb-* to 0.0.45 — reuses a single OffscreenCanvas in the canvas recording worker instead of allocating a new one per frame, fixing a memory leak in Safari where GPU-backed canvas resources were not being garbage collected promptly (2026-03-02) - Updated dependencies [
4f885c0]:- @posthog/types@1.357.0
1.356.2
Patch Changes
-
#3174
e9127d8Thanks @TueHaulund! - Detect and report when rrweb fails to initialize. rrweb'srecord()silently swallows startup errors and returnsundefined, which previously left the SDK reporting an active recording status while capturing zero data. The SDK now checks the return value and reports a newrrweb_errorstatus, making the failure visible in debug properties. (2026-03-02) -
#3175
6ee5f12Thanks @TueHaulund! - Fix memory leak in canvas recording on Safari < 16.4 where ImageBitmaps were never closed when OffscreenCanvas was unavailable in the web worker. (2026-03-02) -
#3178
186871aThanks @TueHaulund! - Skip canvas FPS recording entirely on browsers without OffscreenCanvas support (Safari < 16.4) instead of running a wasteful requestAnimationFrame loop that can never produce data. Also includes displayWidth/displayHeight in canvas mutation data for correct replay sizing. (2026-03-02) -
#3176
87bae20Thanks @dustinbyrne! - fix: Drop explicit exports (2026-03-02) -
#3172
2e46959Thanks @dustinbyrne! - fix: Compressed requests use ArrayBuffer (2026-03-02) -
Updated dependencies []:
- @posthog/types@1.356.2
1.356.0
Minor Changes
- #3142
ec54fd8Thanks @dmarticus! - Add feature_flag_cache_ttl_ms config to prevent stale flag values (2026-02-26)
Patch Changes
-
#3154
a47179cThanks @slshults! - fix: Improve tablet device type detection when Chrome sends desktop-like UA stringsChrome on Android tablets defaults to "request desktop site" mode, sending a UA string indistinguishable from desktop Linux. This uses the Client Hints API (navigator.userAgentData.platform) and touch capability (navigator.maxTouchPoints) to correctly classify these devices as Tablet or Mobile when UA-based detection falls through to the Desktop default. (2026-02-26)
-
#3145
d741668Thanks @dmarticus! - Adds a remote_config_refresh_interval_ms config option to control how often feature flags are automatically refreshed in long-running sessions. (2026-02-26) -
Updated dependencies [
ec54fd8,d741668]:- @posthog/types@1.356.0
1.354.2
Patch Changes
- #3153
67cf41eThanks @dustinbyrne! - fix: Add additional legacy exports for fully qualified dist and lib exports (2026-02-25) - Updated dependencies []:
- @posthog/types@1.354.2
1.354.1
Patch Changes
- #3148
9ae20e7Thanks @dustinbyrne! - fix: Expose all export paths (2026-02-25) - Updated dependencies []:
- @posthog/types@1.354.1
1.354.0
Minor Changes
- #3080
4d0c783Thanks @dustinbyrne! - feat: Introduce internal config to improve tree-shaking (2026-02-25)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.354.0
1.353.0
Minor Changes
- #3135
fba7e5bThanks @dustinbyrne! - feat: Persist $user_state to cookie for server-side access (2026-02-23)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.353.0
1.352.1
Patch Changes
-
#3129
6bfa003Thanks @pauldambra! - fix: no need to put rrweb and friends directly on window in posthog-recorder (2026-02-23) -
#3131
ad26474Thanks @veryayskiy! - Fix issue with toolbar interferring distinct id in conversations (2026-02-23) -
Updated dependencies []:
- @posthog/types@1.352.1
1.352.0
Minor Changes
- #3121
c3c9780Thanks @veryayskiy! - Ability to retrieve previous conversations (2026-02-20)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.352.0
1.351.4
Patch Changes
- #3119
2649a9aThanks @dmarticus! - Adds a fresh option to getFeatureFlag(), getFeatureFlagResult(), and isFeatureEnabled() that only returns values loaded from the server, not cached localStorage values. (2026-02-19) - Updated dependencies [
2649a9a]:- @posthog/types@1.351.4
1.351.0
Minor Changes
- #3115
8655261Thanks @veryayskiy! - Strip markdown in tickets list (2026-02-18)
Patch Changes
- #3107
9dbc05eThanks @ablaszkiewicz! - warning on manual capture('$exception') (2026-02-18) - Updated dependencies [
9dbc05e]:- @posthog/types@1.351.0
- @posthog/core@1.23.1
1.350.0
Minor Changes
- #2895
1b47203Thanks @benjackwhite! - RemoteConfig (config.js) has been loaded for ages and is in use by us in production. This PR makes it the sole config loading mechanism for posthog-js, removing the legacy /flags/?v=2&config=true path and the __preview_remote_config gate. (2026-02-17)
Patch Changes
- Updated dependencies [
1b47203]:- @posthog/types@1.350.0
1.348.0
Minor Changes
- #3108
c4ca045Thanks @veryayskiy! - Support multiple tickets (2026-02-17)
Patch Changes
1.347.2
Patch Changes
-
#3094
0d30218Thanks @TueHaulund! - feat(replay): add $snapshot_max_depth_exceeded debug property and bump rrweb to 0.0.42 with DOM depth limit (2026-02-13) -
#3093
f19b7f2Thanks @TueHaulund! - fix(replay): retry session recording start when persisted remote config is stale (2026-02-13) -
Updated dependencies []:
- @posthog/types@1.347.2
1.345.5
Patch Changes
- #3060
7437982Thanks @pauldambra! - Add missingfeatureFlagsproperty andOverrideFeatureFlagsOptionstype toPostHoginterface, restoreset_configto the loaded callback type, and addfeatureFlagsReloadingtoon()event types (2026-02-11) - Updated dependencies [
7437982]:- @posthog/types@1.345.5
1.345.4
Patch Changes
- #3074
4e7fda9Thanks @marandaneto! - fix: session replay respects the network_timing remote config (2026-02-11) - Updated dependencies []:
- @posthog/types@1.345.4
1.345.3
Patch Changes
- #3064
50ebdfbThanks @jordanm-posthog! - Fixed an issue where Dead Clicks could continue being captured after being disabled via remote config. (2026-02-10) - Updated dependencies [
0acf16f]:- @posthog/core@1.22.0
- @posthog/types@1.345.3
1.345.0
Minor Changes
- #2919
fe8090cThanks @dustinbyrne! - Add$feature_flag_errorproperty to$feature_flag_calledevents (2026-02-09)
Patch Changes
- #3066
90db5d4Thanks @pauldambra! - fix: remote config cache invalidation was too aggressive (2026-02-09) - Updated dependencies [
fe8090c]:- @posthog/types@1.345.0
1.343.1
Patch Changes
- #3051
aa712a3Thanks @pauldambra! - fix: replay remote config cache should be invalidated periodically (2026-02-09) - Updated dependencies []:
- @posthog/types@1.343.1
1.343.0
Minor Changes
- #3048
dd3328fThanks @veryayskiy! - Do not show identification form if user is identified (2026-02-09)
Patch Changes
- #3049
8d9bb16Thanks @pauldambra! - fix: sampled: true in persistence if legacy and should be ignored (2026-02-09) - Updated dependencies []:
- @posthog/types@1.343.0
1.342.1
Patch Changes
- #3039
8f75daeThanks @hpouillot! - fix(err): fix console error capturing (2026-02-06) - Updated dependencies [
8f75dae]:- @posthog/core@1.20.1
- @posthog/types@1.342.1
1.342.0
Minor Changes
- #3032
19d59eaThanks @dmarticus! - add featureFlagsReloading event for tracking flag reload state (2026-02-05)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.342.0
1.340.0
Minor Changes
- #3024
2b2725eThanks @veryayskiy! - Support widget position (2026-02-04)
Patch Changes
- Updated dependencies [
bb62809]:- @posthog/core@1.20.0
- @posthog/types@1.340.0
1.338.0
Minor Changes
- #3020
5ccf27eThanks @veryayskiy! - Fix issue with contrast colors in support widget (2026-02-03)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.338.0
1.337.0
Minor Changes
-
#2996
7768010Thanks @matheus-vb! - Filter out flags marked as failed before merging with cached values, preventing transient backend errors from overwriting previously evaluated flag states (2026-02-03) -
#3000
4a1af3bThanks @veryayskiy! - Render markdown in support product (2026-02-03)
Patch Changes
1.336.2
Patch Changes
-
#2985
2ed9623Thanks @adboio! - support custom banner container for product tours (2026-01-29) -
#2991
2b32a60Thanks @lricoy! - treat undefined and null the same when receiving config (2026-01-29) -
#2973
c1aa45cThanks @lricoy! - make attribution opt-in by default to reduce memory usage (2026-01-29) -
Updated dependencies []:
- @posthog/types@1.336.2
1.336.0
Minor Changes
- #2954
228930aThanks @dustinbyrne! - feat: AddgetFeatureFlagResultmethod (2026-01-28)
Patch Changes
- Updated dependencies [
228930a]:- @posthog/types@1.336.0
1.334.0
Minor Changes
- #2802
f8c17bcThanks @pauldambra! - feat: add external_scripts_inject_target config to control script injection location (2026-01-22)
Patch Changes
-
#2950
8543f0fThanks @fuziontech! - fix(web-vitals): reduce memory leak in SPAs- Upgrade web-vitals from v4.2.4 to v5.1.0 (includes internal memory fixes from v5.0.3)
- Remove duplicate observer creation on URL change
Note: web-vitals has inherent memory accumulation in SPAs due to internal state. The v5 upgrade reduces this but doesn't fully eliminate it since web-vitals doesn't provide cleanup functions (Issue #629 was closed as "not planned"). (2026-01-22)
-
Updated dependencies []:
- @posthog/types@1.334.0
1.333.0
Minor Changes
- #2942
994206dThanks @veryayskiy! - Send context on sendMessage (2026-01-21)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.333.0
1.331.2
Patch Changes
- #2939
6442f5dThanks @dustinbyrne! - fix: Rate limiting configuration changes are respected (2026-01-20) - Updated dependencies []:
- @posthog/types@1.331.2
1.331.0
Minor Changes
-
#2900
23770e9Thanks @dmarticus! - RenamedevaluationEnvironmentstoevaluationContextsfor clearer semantics. The term "contexts" better reflects that this feature is for specifying evaluation contexts (e.g., "web", "mobile", "checkout") rather than deployment environments (e.g., "staging", "production").Deprecated
posthog.initoptionevaluationEnvironmentsis now deprecated in favor ofevaluationContexts. The old property will continue to work and will log a deprecation warning. It will be removed in a future major version.
Migration Guide
// Before posthog.init('<ph_project_api_key>', { evaluationEnvironments: ['production', 'web', 'checkout'], }) // After posthog.init('<ph_project_api_key>', { evaluationContexts: ['production', 'web', 'checkout'], }) ``` (2026-01-19)
Patch Changes
- Updated dependencies [
23770e9]:- @posthog/core@1.11.0
- @posthog/types@1.331.0
1.330.0
Minor Changes
- #2929
6695383Thanks @veryayskiy! - Add more context to a ticket when created (2026-01-19)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.330.0
1.329.0
Minor Changes
- #2927
da78b8cThanks @veryayskiy! - Remove loading state in support product (2026-01-19)
Patch Changes
- #2926
3676972Thanks @pawel-cebula! - Fix TypeError when logging objects with null/undefined property values in flattenObject (2026-01-19) - Updated dependencies []:
- @posthog/types@1.329.0
1.328.0
Minor Changes
- #2925
ce4566dThanks @TueHaulund! - Restore fetch wrappers to most recent working version (2026-01-17)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.328.0
1.327.0
Minor Changes
- #2923
b8b7f90Thanks @TueHaulund! - Fixed issue with fetch wrappers reconsuming request bodies and generating mismatched FormData boundaries (2026-01-17)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.327.0
1.325.0
Minor Changes
- #2913
262cb4bThanks @TueHaulund! - Ensure we always pass RequestInit object to wrapped fetch (2026-01-16)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.325.0
1.323.0
Minor Changes
- #2902
584657aThanks @TueHaulund! - Ensure wrapped fetch() passes duplex option when required (2026-01-15)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.323.0
1.322.0
Minor Changes
- #2904
b9fb2e2Thanks @veryayskiy! - Fix the issue with _currentTicketId (2026-01-15)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.322.0
1.320.0
Minor Changes
- #2875
7662025Thanks @lucasheriques! - chore(deps): bump preact from 10.19.3 to 10.28.0 to fix security vulnerability (2026-01-13)
Patch Changes
- Updated dependencies []:
- @posthog/types@1.320.0
1.319.2
Patch Changes
- #2864
f64ebefThanks @rafaeelaudibert! - We were missing some public definitions inside@posthog/typesso let's fix them here. We've also fixed the typing inside theloadedcallback (2026-01-13) - Updated dependencies [
f64ebef]:- @posthog/types@1.319.2
1.319.0
Minor Changes
Patch Changes
- #2873
ec5b64bThanks @pauldambra! - fix: use property based testing to expose another edge case bug in checkAndGetSessionAndWindowId (2026-01-12) - Updated dependencies []:
- @posthog/types@1.319.0
1.318.2
Patch Changes
- #2871
4f73495Thanks @pauldambra! - fix: detecting activity timestamp should not compare null to numbers (2026-01-12) - Updated dependencies []:
- @posthog/types@1.318.2
1.316.1
Patch Changes
-
#2846
5ce7252Thanks @ordehi! - Fix survey URL prefill to respect branching/skip logicWhen using URL parameters to prefill survey responses (e.g.,
?q0=9), the SDK now correctly respects the survey's branching configuration. Previously, prefilled answers would always advance to the next sequential question, ignoring any skip logic. (2026-01-09) -
Updated dependencies []:
- @posthog/types@1.316.1
1.316.0
Minor Changes
- #2851
d4bf005Thanks @veryayskiy! - Expose Conversations API Methods for Custom UI (2026-01-08)
Patch Changes
- #2856
c1ed63bThanks @marandaneto! - chore: expose default stack parser creator (2026-01-08) - Updated dependencies [
fba9fb2,c1ed63b]:- @posthog/core@1.9.1
- @posthog/types@1.316.0
1.315.0
Minor Changes
-
#2849
8ddf472Thanks @veryayskiy! - separate enable conversation with enable conversations widget (2026-01-06) -
#2839
83b03feThanks @rafaeelaudibert! - Release new @posthog/types library to make it easy for those using the script version ofposthog-jsto properly typewindow.posthog(2026-01-06)
Patch Changes
- Updated dependencies [
83b03fe]:- @posthog/types@1.315.0
1.313.0
Minor Changes
- #2832
f050f6cThanks @rafaeelaudibert! - Introduce custom cookie properties for localStorage+cookie persistence using the newcookie_persisted_propertiesproperty. This allows people to opt-in to store properties in cookies even inlocalstorage+cookiesmode (2026-01-01)
1.312.0
Minor Changes
-
#2834
548b466Thanks @ordehi! - fix: ClearPageViewManagerstate on session rotation to prevent cross-session duration pollutionWhen a browser tab is backgrounded and the session rotates (30 min idle or 24 hour max),
PageViewManagernow clears its state. This prevents$prev_pageview_durationfrom spanning session boundaries, which was causing impossibly large values (94+ hours observed) in web analytics "Average Time on Page" metrics.Users who implemented workarounds for inflated
$prev_pageview_durationvalues (e.g., capping at 30 minutes) may want to review those after upgrading, as the root cause is now fixed. (2025-12-31)
1.311.0
Minor Changes
-
#2813
4b7443cThanks @ordehi! - feat(flags): add updateFlags() method for injecting flags without network requestAdds
posthog.updateFlags(flags, payloads?, options?)to inject feature flag values from an external source (e.g., server-side evaluation, edge middleware) without making a network request. Supports{ merge: true }option to merge with existing flags instead of replacing. (2025-12-29)
1.310.2
Patch Changes
-
#2812
ad42eaeThanks @lucasheriques! - fix(surveys): queue callbacks when fetch is in progress instead of returning error (2025-12-29) -
#2814
3da6a4cThanks @jurajmajerik! - Persist $device_id to cookies so it survives localStorage clears (2025-12-29)
1.310.0
Minor Changes
-
#2770
6851061Thanks @daibhin! - feat: allow exception autocapture to be programatically enabled / disabled (2025-12-22) -
#2792
f7372c8Thanks @adboio! - add event/action triggers for product tours (2025-12-22) -
#2790
96f42beThanks @adboio! - fix: hosted survey auto-submit behavior only submits skipped questions (2025-12-22) -
#2786
2c54d15Thanks @adboio! - emit new "survey abandoned" event on pageleave (2025-12-22) -
#2787
b676b4dThanks @lucasheriques! - feat: allow customizing text colors on web and react native (2025-12-22)
Patch Changes
- Updated dependencies [
b676b4d]:- @posthog/core@1.9.0
1.306.2
Patch Changes
- #2730
79184bdThanks @ablaszkiewicz! - include synthetic exception in console.error capture (2025-12-15)
1.301.2
Patch Changes
-
#2690
e9c00fdThanks @robbie-c! - Related to https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182We didn't include any of the vulnerable deps in any of our packages, however we did have them as dev / test / example project dependencies.
There was no way that any of these vulnerable packages were included in any of our published packages.
We've now patched out those dependencies.
Out of an abundance of caution, let's create a new release of all of our packages. (2025-12-04)
-
Updated dependencies [
e9c00fd]:- @posthog/core@1.7.1
1.301.1
Patch Changes
- #2666
2004d36Thanks @pauldambra! - fix: session id rotation relied on in-memory cache which would be stale after log idle periods - particularly with multiple windows in play (2025-12-04)
1.300.0
Minor Changes
- #2603
e1617d9Thanks @dmarticus! - add $feature_flag_evaluated_at properties to $feature_flag_called events (2025-12-03)
Patch Changes
-
#2670
4487d6bThanks @pauldambra! - A click while holding a modifier key (CTRL, ALT, CMD, Windows) shouldn't ever count as a dead click - so that we don't pick up e.g. open in a new tab as a dead click (2025-12-03) -
#2677
0e67750Thanks @lucasheriques! - chore: allow customizing text input and background for surveys (2025-12-03) -
Updated dependencies [
e1617d9]:- @posthog/core@1.7.0
1.299.0
Minor Changes
-
#2641
f9c4dbaThanks @adboio! - add survey cancellation events (2025-12-01) -
#2642
37e4f76Thanks @rafaeelaudibert! - Add newpayloadentry to theEarlyAccessFeaturetype (2025-12-01) -
#2661
aaad806Thanks @adboio! - add support for surveys triggered by actions with event property filters (2025-12-01)
Patch Changes
- #2582
21365ffThanks @pauldambra! - fix: properly cleanup in network plugin (2025-12-01)
1.298.1
Patch Changes
- #2592
7782dd9Thanks @marandaneto! - fix: session replay on react native web (2025-11-24)
1.298.0
Minor Changes
- #2619
86dab38Thanks @hpouillot! - package deprecation (2025-11-24)
Patch Changes
- Updated dependencies [
86dab38]:- @posthog/core@1.6.0
1.297.0
Minor Changes
- #2578
91f41eeThanks @rafaeelaudibert! - Output confirmation log message to the user when overriding feature flags to improve user feedback on whether the action actually did something or not (2025-11-19)
Patch Changes
- #2575
8acd88fThanks @hpouillot! - fix frame platform property for $exception events (2025-11-19) - Updated dependencies [
8acd88f]:- @posthog/core@1.5.3
1.296.1
Patch Changes
- #2590
ab85422Thanks @pauldambra! - fix: don't rely on order of method calls to gate calling url
1.293.0
Minor Changes
- #2565
f2426dbThanks @pauldambra! - feat: ignore rageclicks by content.
Patch Changes
- #2570
de80a41Thanks @pauldambra! - fix: rageclick detection should use event timestamp not current time
1.292.0
Minor Changes
- #2519
7c16ff7Thanks @rodrigomarcolin! - Made rageclick detection fully parametrizable with configurable threshold_px, timeout_ms, and click_count, while preserving previous default behavior.
1.291.0
Minor Changes
- #2557
c8c7de2Thanks @pauldambra! - feat: support strict minimum duration (more accurate on full page load)
1.290.0
Minor Changes
- #2553
8a2b790Thanks @pauldambra! - feat: yield to the main thread during posthog init
1.289.0
Minor Changes
- #2551
10be1b0Thanks @dmarticus! - Support bootstrapping feature flags during SSR in ReactJS
1.286.0
Minor Changes
- #2547
cd8bcd7Thanks @TueHaulund! - Fixed a bug where configuration overrides for session recording would not be applied if the recorder module was still loading
1.285.1
Patch Changes
- #2545
c26a12cThanks @pauldambra! - fix: allow session ending payload when recording is idle
1.285.0
Minor Changes
- #2503
e95a9d5Thanks @pauldambra! - feat: store previous and next session id in session recording
1.284.0
Minor Changes
-
#2529
882d823Thanks @MattBro! - feat(surveys): add URL prefill and auto-submit supportSurveys can now be prefilled and automatically submitted via URL parameters.
New configuration options:
posthog.init('token', { surveys: { prefillFromUrl: true, autoSubmitIfComplete: true, autoSubmitDelay: 800, }, })URL format:
?q0=1&q1=8&auto_submit=trueq{N}= question index (0-based)- Value = choice index or rating value
auto_submit=trueenables auto-submission
Supported question types:
- Single choice (choice index)
- Multiple choice (multiple q{N} params)
- Rating (numeric value, validated against scale)
Use cases:
- Pre-filled NPS surveys from email campaigns
- One-click survey responses from notifications
- SMS surveys with embedded feedback
- QR code surveys at events
1.282.0
Minor Changes
- #2517
46e3ca6Thanks @pauldambra! - feat: add a component that will wrap your components and capture an event when they are in view in the browser
Patch Changes
- #2517
46e3ca6Thanks @pauldambra! - fix: complete react sdk featureflag component refactor
1.281.0
Minor Changes
- #2502
751b440Thanks @pauldambra! - fix: bucketed rate limiter can calculate tokens without a timer
Patch Changes
-
#2500
71ae0d2Thanks @pauldambra! - fix: don't poll surveys while the page is hidden -
Updated dependencies [
751b440]:- @posthog/core@1.4.0
1.280.1
Patch Changes
-
#2492
2b13291Thanks @pauldambra! - fix: extendUrlParams should always replace unless the caller says otherwise -
#2491
130c9e0Thanks @pauldambra! - fix: correctly update the retry count URL parameter -
#2485
d7dced1Thanks @pauldambra! - fix: stop polling when the retry queue is empty
1.279.3
Patch Changes
1.279.1
Patch Changes
- #2469
b161bb3Thanks @pauldambra! - fix: stop heatmap buffer interval when hidden
1.279.0
Minor Changes
- #2463
3075888Thanks @pauldambra! - fix: remove rrweb types as a peer dependency
1.276.0
Minor Changes
- #2444
d50899eThanks @pauldambra! - chore: bump posthog rrweb version - not generally used yet
1.275.2
Patch Changes
-
#2431
7d45a7aThanks @marandaneto! - fix: remove deprecated attribute $exception_personURL from exception events -
Updated dependencies [
daf919b,7d45a7a]:- @posthog/core@1.3.0
1.275.1
Patch Changes
- #2422
4e15fdaThanks @pauldambra! - fix: possible memory leak in session id replacement in cookieless mode
1.275.0
Minor Changes
- #2426
ae941c2Thanks @thmsobrmlr! - Apply $current_url masking in web vitals and heatmaps extensions.
1.274.3
Patch Changes
- #2423
2d4eac4Thanks @pauldambra! - fix: another small potential memory leak in the recorder wrapping code"
1.274.2
Patch Changes
- #2421
43b8029Thanks @pauldambra! - fix: potential source of memory leak in recorder mutation throttler
1.274.0
Minor Changes
- #2404
39ace01Thanks @pauldambra! - feat: remove eager loaded replay and reduce bundle size by 14.8%
Patch Changes
- Updated dependencies [
e19a384]:- @posthog/core@1.2.3
1.273.1
Patch Changes
- #2412
25a8846Thanks @pauldambra! - fix: rely on 'state' less when reporting replay status
1.273.0
Minor Changes
- #2408
66b12f8Thanks @thmsobrmlr! - Fixes an issue where the event queue was not started until a page reload after callingopt_in_capturing()
1.272.1
Patch Changes
- #2395
4a39a10Thanks @pauldambra! - fix: increase max depth for app state diffing
1.272.0
Minor Changes
- #2405
cdfbd6dThanks @pauldambra! - fix: session recording config can be false, correct the types
1.271.0
Minor Changes
- #2385
7373238Thanks @pauldambra! - feat: switch replay to lazy loaded by default"
1.270.1
Patch Changes
- #2390
244b3adThanks @hpouillot! - fix react sourcemaps - revert: #2390 to fix persistence bug with surveys
1.270.0
Minor Changes
- #2355
9eccbabThanks @lucasheriques! - fix: use persistence for surveys if localStorage usage is enabled
Patch Changes
- #2396
13c6667Thanks @pauldambra! - fix: no need to estimate the size of all rrweb events before compressing some of them
1.269.1
Patch Changes
- #2393
a3b64e6Thanks @pauldambra! - chore: variable rename so i can trigger a releas
1.269.0
Minor Changes
- #2369
2a6ea65Thanks @dmarticus! - This PR implements support for evaluation environments in the posthog-js SDK, allowing users to specify which environment tags their SDK instance should use when evaluating feature flags.
1.268.9
Patch Changes
-
#2378
b920bacThanks @pauldambra! - fix: don't mangle to $ in no external or es5 builds -
#2376
b5eb605Thanks @pauldambra! - fix: rotating buffer while trigger pending
1.268.6
Patch Changes
- #2368
2102ee4Thanks @pauldambra! - fix: recorder behaviour when idle session is force terminated then restarted
1.268.5
Patch Changes
- #2362
8b570b8Thanks @pauldambra! - fix: over eager rename left a couple of old versions trying to call onRemoteConfig that doesn't exist
1.268.1
Patch Changes
- #2315
fd2c51dThanks @pauldambra! - fix: lazy loaded replay relies on remote config having been persisted in storage to avoid race with config on restart
1.268.0
Minor Changes
- #2345
4f37e77Thanks @lucasheriques! - feat: surveys matching on event properties
1.267.0
Minor Changes
- #2347
5d13bedThanks @pauldambra! - feat: allow ignoring rageclicks on elements by css selector
1.266.1
Patch Changes
-
#2330
da07e41Thanks @hpouillot! - use error tracking processing from core -
Updated dependencies [
da07e41]:- @posthog/core@1.1.0
1.266.0
Minor Changes
- #2321
b81e152Thanks @pauldambra! - feat: expose rrweb custom events on the public interface of the recorder. not intended for arbitrary public use but useful for internal purposes
1.265.0
Minor Changes
- #2032
822d8dfThanks @lucasheriques! - feat: allow display surveys popups on demand
1.263.0
Minor Changes
- #2294
5137440Thanks @pauldambra! - feat: add a redux logging middleware to posthog-js
1.262.1
Patch Changes
- #2309
28223c1Thanks @pauldambra! - fix: default to eager loading replay while investigating trigger bug reports
1.262.0
Minor Changes
- #2296
f9fe3baThanks @pauldambra! - feat: switch replay default to lazy loading
1.261.8
Patch Changes
- #2276
97961e4Thanks @dustinbyrne! -isFeatureEnablednow returnsundefined(instead offalse) for missing or disabled feature flags, aligning with the documentation. Previously,undefinedwas returned only before flags had loaded, and missing/disabled flags returnedfalse. This change clarifies the difference between flags that exist but don't match (false) and flags that don’t exist or are disabled (undefined).
1.261.7
Patch Changes
- #2284
bdfe450Thanks @pauldambra! - fix: order of operations when replay does pageview fallback
1.261.5
Patch Changes
- #2270
980f5c4Thanks @lucasheriques! - fix: hosted surveys should ignore any delays
1.261.4
Patch Changes
- #2268
999c63fThanks @pauldambra! - fix: session recorder wrapper had private field that should be public"
1.261.3
Patch Changes
- #2267
f2ac956Thanks @pauldambra! - feat: allow testing of the new lazy loaded session recorder
1.261.2
Patch Changes
-
#2266
9470d97Thanks @pauldambra! - fix: don't mangle variables to `# posthog-js -
#2265
2487d12Thanks @pauldambra! - chore: update to latest rollup and terser
1.261.1
Patch Changes
- #2263
41d3890Thanks @pauldambra! - chore: add unused lazy loaded session recorder to prime CDN
1.260.2
Patch Changes
- #2236
f3269f3Thanks @lucasheriques! - fix: set survey person properties on SDK <1.249.2
1.260.1
Patch Changes
- #2215
1e95d47Thanks @lucasheriques! - fix: always set surveySeen on local storage for old posthog-js versions
1.258.5
Patch Changes
- #2178
db569faThanks @lucasheriques! - - Fix surveys loading with advanced_enable_surveys config
1.258.4
Patch Changes
- #2172
ac254d9Thanks @lucasheriques! - Adds a new config,advanced_enable_surveys, to always enable surveys funcionality in the SDK
1.258.3
Patch Changes
-
#2171
14adc01Thanks @lucasheriques! - Fix early access features accumulation in persistence -
#2170
262cc5cThanks @lucasheriques! - Removes the_renderExternalSurveymethod which is not needed anymore
1.258.2
Patch Changes
- #2111
7114593Thanks @pauldambra! - checks for session activity in other windows when timing out in any particular window, avoids a race condition when proactively marking a session as idle
1.258.1
Patch Changes
- #2120
c7b03cdThanks @lucasheriques! - Updates the renderSurvey and getActiveMatchingSurveys methods to not take any external surveys into consideration