Packages

posthog-js

1.438.13 · 20 Oct 2026(Apache-2.0 AND MIT)10.1M / weekRepositoryHomepagenpmAtom feed

1421 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.

  1. 1.415.3

    11 Aug 2026
    • replay: never ship a buffer swapped in by a re-entrant session rotation mid-flush
      (2026-08-11)

    • dependencies updates: - Updated dependency dompurify@^3.4.13 ↗︎ (from ^3.4.12, in dependencies) (2026-08-11)

    • replay: stop dropping adopted stylesheets that arrive before the host's shadow root is attached. When the recorder's full snapshot races a web component's hydration, the AdoptedStyleSheet event can be recorded before the mutation that attaches the host's shadow root. The replayer silently dropped those styles for the rest of the page view, so components styled via shadowRoot.adoptedStyleSheets (Stencil, Lit) rendered completely unstyled. The replayer now constructs the stylesheet even when the shadow root does not exist yet and keeps retrying adoption until it is attached.
      (2026-08-11)

  2. 1.415.2

    11 Aug 2026
    • Support removing multiple persisted properties in one operation.
      (2026-08-11)

  3. 1.415.1

    10 Aug 2026
    • replay: don't open a recording that holds only idle lifecycle markers
      (2026-08-10)

  4. 1.415.0

    10 Aug 2026
    • surveys: optional intro screen shown before the first question

      Surveys can now display an intro screen before question 1, configured via the new
      displayIntroScreen, introScreenHeader, introScreenDescription,
      introScreenDescriptionContentType, and introScreenButtonText appearance fields.
      The intro is dismissed with a button and records no response, does not affect
      completion or partial-response metrics, does not re-fire "survey shown", and is
      skipped when a survey is resumed with answers in progress. Intro copy is
      translatable like the thank-you message. renderSurveysPreview accepts
      previewPageIndex: -1 (exported as INTRO_SCREEN_PREVIEW_INDEX) to preview the
      intro screen. (2026-08-10)

  5. 1.414.0

    7 Aug 2026
    • Add posthog.conversations.getUnavailableReason() to expose why the conversations API is unavailable (bundle blocked/failed to load, disabled in project, remote config pending/failed, still initializing, …) instead of collapsing every case into isAvailable() === false. Lets callers that fall back to another channel record the specific cause. ConversationsUnavailableReason is exported from the package entry points, so consumers can name the type.
      (2026-08-07)

  6. 1.413.3

    6 Aug 2026
    • Clear properties registered for a session when the PostHog session rotates.
      (2026-08-06)

    • Persist in-place object and array mutations when properties are re-registered.
      (2026-08-06)

    • Make the session replay attribute masking options mutually exclusive: when both maskAllElementAttributes and maskAttributeFn are set, the coarse option wins and the callback is ignored (with a console warning), so a callback can no longer accidentally unmask what maskAllElementAttributes hides.
      (2026-08-06)

  7. 1.413.2

    5 Aug 2026
    • Fix a benign network failure (e.g. TypeError: Failed to fetch) in the async native-gzip request path surfacing as an unhandled promise rejection, which exception autocapture would otherwise pick up
      (2026-08-05)

  8. 1.413.1

    5 Aug 2026
    • Contain and log recorder-owned callback failures while preserving exceptions from patched native host APIs. Keep recording mutations from adopted cross-realm nodes.
      (2026-08-05)

    • replay: preserve privacy masking for initial network metadata

      Initial navigation and performance-timing entries are now passed through maskCapturedNetworkRequestFn, including when they have no method. URL rewrites are respected. When the callback returns nullish for an initial entry, replay-required timing metadata is retained without its URL, headers, or body so method-gated callbacks do not drop the metadata or expose deliberately filtered customer data. Derived server-timing entries are also suppressed when this strict fallback is used. Enforced PostHog filtering and payload cleaning still run first. (2026-08-05)

  9. 1.413.0

    5 Aug 2026
    • Add attribute-level masking to session replay: maskAttributeFn provides per-attribute control over the final serialized value, while maskAllElementAttributes masks all source DOM string attributes (including rendering attributes and synthesized form values) at the cost of replay fidelity.
      (2026-08-05)

    • replay: discard held interaction-less recordings when a background document unloads without ever becoming visible
      (2026-08-05)

  10. 1.412.2

    5 Aug 2026
    • replay: discard held interaction-less recordings when a background document unloads without ever becoming visible
      (2026-08-05)

  11. 1.412.1

    5 Aug 2026
    • security

      Update PostCSS to include upstream security fixes.
      (2026-08-05)

  12. 1.412.0

    5 Aug 2026
    • Bound the main-thread cost of the recorder's initial full snapshot, and start measuring it.

      stringifyStylesheet reads cssText for every CSSRule of every stylesheet, all inside the one uninterruptible task that takes the full snapshot. On CSS-heavy pages that is the dominant cost, and it has been observed freezing the UI (no rendering, scrolling, or cursor movement) for seconds. The existing maxDepth guard doesn't help, since it only bounds deep DOMs, not wide ones or heavy CSS.

      Stylesheet inlining now stops after a budget of CSSRules per snapshot (session_recording.inlineStylesheetBudgetRules, default 10,000; set 0 for the previous unbounded behaviour). Sheets past the budget are serialized without _cssText, keeping rel/href so replay can load them remotely, and are then inlined one per idle callback and delivered as attribute mutations. Replay fidelity is preserved; the work is just no longer one long blocking task.

      The snapshot's cost is also now measured and reported on captured events, so slow snapshots are visible without a browser profile: $sdk_debug_replay_slowest_full_snapshot_ms, $sdk_debug_replay_slowest_full_snapshot_stylesheet_ms, $sdk_debug_replay_slowest_full_snapshot_nodes, $sdk_debug_replay_slowest_full_snapshot_css_rules, $sdk_debug_replay_deferred_stylesheets, and, for the incremental path, $sdk_debug_replay_slowest_mutation_batch_ms. (2026-08-05)

  13. 1.411.0

    4 Aug 2026
    • add opt-in capture_performance.__preview_web_vitals_soft_navs to fix inflated web vitals on single-page apps

      Client-side route changes in SPAs previously left web vitals (LCP especially) accumulating against the original hard-navigation timestamp, inflating the top tail of Core Web Vitals. Setting capture_performance: { __preview_web_vitals_soft_navs: true } now scopes metrics to the browser's Soft Navigation entries so each route change starts a fresh measurement window. It's a preview option because it relies on Chrome's experimental Soft Navigation Detection API and loads pinned stable web-vitals 6.x callbacks; when disabled (the default), the existing web-vitals 5.x behavior remains unchanged. (2026-08-04)

    • Keep $referring_domain and canonical utm_*/campaign parameters on minimal $feature_flag_called events. Previously the minimal allowlist stripped every campaign parameter, so a flag-called event landing first in a session could set the session's UTM attribution and channel type to NULL in web analytics.
      (2026-08-04)

  14. 1.410.10

    4 Aug 2026
    • Fix inline surveys rendering an empty container when a stale persisted question index (left over from a prior completion) points past the last question. When the persisted index is out of range the whole in-progress record is now discarded and the survey starts fresh, instead of clamping the index while keeping the equally-stale responses and visited indices. Restored visited indices are also filtered to valid questions so the Back button can never navigate to a non-existent question and re-empty the container.
      (2026-08-04)

    • replay: hold fresh interaction-less session recordings until there is evidence someone cares

      A tab that loads but never sees any user interaction (prefetched pages, background tabs, in-app browser preloads) no longer ships a billable recording while it sits untouched. Like rotation-born sessions, a fresh recording epoch is held until there is evidence someone cares about it: a user interaction, an event trigger match, or an explicit override (posthog.startSessionRecording(...)) releases the hold and ships the buffer on the normal flush cadence, so released recordings are playable from the session's start. A clean unload also ships a fresh-start hold, so passive visits (reading, watching a video) are still captured exactly as before; rotation-born holds are discarded on unload as before. A held buffer that reaches the size cap is dropped to bound memory, and a later release takes a fresh full snapshot so the recording resumes playable. (2026-08-04)

    • Fix held rotation-born session replay buffers not flushing when a V2 event trigger matches
      (2026-08-04)

  15. 1.410.9

    4 Aug 2026
    • warn when reset() silently opts the user back out

      reset() clears stored consent along with the rest of the user's state. With opt_out_capturing_by_default, this returns the instance to the opted-out default, so calling reset() after opt_in_capturing() would stop capturing without warning. It now logs a warning when that happens and documents the required ordering. (2026-08-04)

    • Fix event-triggered survey popup delays resetting on every page navigation. The popup delay now resumes from when the trigger fired (persisted for the session) instead of restarting a fresh countdown on each page load, so a survey configured with an event/action trigger and a popup delay no longer gets lost when the user navigates before the delay elapses.
      (2026-08-04)

  16. 1.410.8

    4 Aug 2026
    • Publish TypeScript declarations for browser extension entrypoints under their public dist paths.
      (2026-08-04)

  17. 1.410.7

    4 Aug 2026
    • Avoid promoting handled transport failures to error logs in surveys, product tours, remote config, conversations, and logs while preserving error severity for HTTP and unexpected failures.
      (2026-08-04)

  18. 1.410.6

    3 Aug 2026
    • Fix session replay shipping one billable recording per session rotation for tabs the user never interacts with. A session born from an idle rotation now holds its buffer until the first user interaction, then ships a recording playable from the session's start; without interaction nothing is sent — a further rotation, stop, opt-out, or page unload discards the held data instead of shipping it. An event trigger match (for example record-on-exception) also releases the hold, since it is explicit intent to record the session.
      (2026-08-03)

  19. 1.410.5

    3 Aug 2026
    • Fix selector-widget surveys being abruptly removed while open when their trigger element is unmounted from the DOM (e.g. a dropdown or menu that hosts the trigger closes). The survey is now kept in place while open and only torn down once the user has closed it. Also fixes a related leak where, if the selector resolved to a different element while the survey was open, the old element's click listener was never removed and kept dispatching the show-widget event for the lifetime of the page.
      (2026-08-03)

  20. 1.410.4

    3 Aug 2026
    • Preserve messages, source locations, and existing stacks from browser errors that do not provide a same-realm Error object.
      (2026-08-03)

  21. 1.410.3

    3 Aug 2026
    • Conversations widget: bullet and numbered lists in a support reply now keep their markers on host pages with an aggressive CSS reset (for example Tailwind preflight's ol, ul { list-style: none }). The widget renders into the host page's DOM, so the list style is now set inline on <ul>, <ol>, and <li> rather than left to the page's own styles.
      (2026-08-03)

  22. 1.410.2

    3 Aug 2026
    • Conversations widget: treat a network-level message send failure (ad blocker, offline, CORS, page teardown) as transient — the widget now shows a "check your connection" message and logs at warn instead of error, so these benign failures no longer show up as captured exceptions in error tracking.
      (2026-08-03)

    • Prevent duplicate snippet loaders from replacing an initialized instance or replaying queued calls more than once, and warn with actionable guidance when init() is called again with a different project token
      (2026-08-03)

  23. 1.410.1

    3 Aug 2026
    • Prevent the inline canvas recording worker from requesting an unusable source map from its blob URL.
      (2026-08-03)

  24. 1.410.0

    3 Aug 2026
    • Add session_recording.sampling to disable or throttle mousemove capture (and optionally mouseInteraction) in session replay. Canvas recording now merges its canvas sampling with user-provided sampling instead of overwriting it.
      (2026-08-03)

    • Share extension bundle types between the slim and slim no-external entrypoints.
      (2026-08-03)

  25. 1.409.6

    3 Aug 2026
    • Mark our bundles as third-party code in the source maps we publish (the x_google_ignoreList extension). Browser devtools now attribute console.* messages to the code that called them instead of to posthog-js's console wrapper, which previously showed every message as coming from logs.ts when captureConsoleLogs or session replay's enable_recording_console_log was enabled.
      (2026-08-03)

  26. 1.409.5

    31 Jul 2026
    • Fail open when an error tracking suppression rule cannot be evaluated, so an unknown operator or a key outside $exception_types / $exception_values no longer drops the exception.
      (2026-07-31)

  27. 1.409.4

    31 Jul 2026
    • Fix canvases staying blank after seeking in session replay by re-sending one frame per canvas after each full snapshot
      (2026-07-31)

  28. 1.409.3

    31 Jul 2026
    • Fix hosted (external) surveys with URL prefill: the auto-submitted response now includes caller-provided event properties (extra URL query params), and a later manual submit no longer clears the prefilled answer from the partial-response merge.
      (2026-07-31)

  29. 1.409.2

    31 Jul 2026
    • Avoid redacting session replay network bodies when timestamps or UUID fragments resemble social security or credit card numbers.
      (2026-07-31)

  30. 1.409.1

    31 Jul 2026
    • Add the browser-v1 client adapter for shared extensions, including analytics, request, persistence, replayed remote-config outcomes, and synchronous best-effort cleanup.
      (2026-07-31)

  31. 1.409.0

    30 Jul 2026
    • Emit the release id that posthog-cli injects into your bundle as $release_id on $exception events, so PostHog can attach exceptions to a release without joining through symbol sets. Adds getInjectedReleaseId() to @posthog/core. The property is only attached when an injected release id can be read.
      (2026-07-30)

  32. 1.408.3

    30 Jul 2026
    • Refresh campaign parameters after SPA URL changes.
      (2026-07-30)

    • Fix identify() creating a person profile when the supplied ID already matches an anonymously persisted distinct ID.
      (2026-07-30)

  33. 1.408.2

    30 Jul 2026
    • Fix dead-click false positives on WebKit when the SDK uses an iframe-sourced MutationObserver fallback.
      (2026-07-30)

  34. 1.408.1

    30 Jul 2026
    • The replayer can now yield to the event loop while fast-forwarding to a seek target, via the new opt-in seekYieldBudgetMs player config. Seeking in a long, event-dense recording rebuilds the target frame by re-applying every event since the last full snapshot in one uninterrupted main-thread pass, which can block the page for many seconds and trigger the browser's "Page Unresponsive" dialog; when a yield budget is set, the rebuild runs in time-budgeted chunks instead, and a newer seek cancels any rebuild still in flight so rapid scrubbing only pays for the last seek. A superseded rebuild also resets the machine's lastPlayedEvent so the next seek performs a full rebuild rather than trusting a partially-applied history. The default (0) keeps the previous fully-synchronous behavior.
      (2026-07-30)

  35. 1.408.0

    29 Jul 2026
    • Add canvas mask regions to session replay canvas capture: session_recording.canvasCapture.maskRegionsFn is called once per canvas per captured frame, and the returned regions (CSS pixels, relative to the canvas) are painted black in the captured frame before it is encoded — letting apps that render into canvas (e.g. Flutter web via CanvasKit) mask content that DOM-based masking cannot see.

      The return value decides what happens to that canvas's frame:

      Configuring maskRegionsFn also disables canvas pixel serialization in DOM full snapshots (rr_dataURL) — that path never sees the mask regions, so skipping it closes the route that could otherwise embed unmasked canvas stills in a snapshot; the canvas repaints from the masked frame stream instead. Every canvas the provider answers — with regions or `` — re-sends an unchanged frame as a keyframe every 30s, so after a full snapshot or a seek an idle canvas repaints within at most 30s.

      An app whose real provider only exists once its runtime has booted chooses what happens in between by what it declares in posthog.init: a function covering the whole canvas blacks those frames out, () => null skips them, and declaring nothing records them. Client-side only, cannot be set via remote configuration. (2026-07-29)

  36. 1.407.8

    29 Jul 2026
    • react: restore CommonJS default import interop in UMD bundles

      React hooks used without a PostHogProvider now receive the default PostHog instance again when the UMD build is loaded through CommonJS. (2026-07-29)

  37. 1.407.7

    29 Jul 2026
    • surveys: only wait for feature flags on surveys that repeat

      Surveys stopped being shown while feature flags were still loading, even when a cached
      enabled value for their internal targeting flag was already available. Popover and widget
      surveys recovered on the next evaluation, but a survey your own code renders (type api)
      is evaluated once, so it was dropped for that page load and never reappeared.

      That wait is only needed for surveys that repeat, where stored per-survey state is keyed by
      iteration and cannot be relied on to record that someone already answered. Other surveys
      keep one stable key that already prevents a repeat display, so they are now evaluated
      against the cached flag right away. (2026-07-29)

  38. 1.407.6

    29 Jul 2026
    • Fix extension bundles when used with the slim no-external browser build.
      (2026-07-29)

  39. 1.407.5

    28 Jul 2026
    • Fix paused replay seeks at an exact full snapshot timestamp so the snapshot frame is rebuilt before playback pauses.
      (2026-07-28)

  40. 1.407.4

    28 Jul 2026
    • Send session recording request timestamps in request bodies instead of query strings.
      (2026-07-28)

  41. 1.407.3

    27 Jul 2026
    • Fix canRenderSurvey / canRenderSurveyAsync reporting a survey as renderable before its event/action activation trigger has fired. Surveys gated on a "User sends events" filter are now only eligible once the trigger event is received.
      (2026-07-27)

    • Send analytics request timestamps in capture bodies while retaining query timestamps for session recordings.
      (2026-07-27)

    • Send SDK library identity in feature flag person properties instead of URL query parameters.
      (2026-07-27)

  42. 1.407.2

    23 Jul 2026
    • Fix session replay recordings being unplayable after the session rotated in a tab with no user interaction. When a session expired and rotated (for example in a long-lived background tab), a recorder that had not yet seen user interaction kept attributing snapshots — including full snapshots — to the previous session, so the new session never received a playable full snapshot. The recorder now restarts on rotation in this state, re-syncs its session id from the session manager if they ever diverge, and flushes its buffer on the normal cadence before the first user interaction instead of holding data until the next rotation or page unload.
      (2026-07-23)

  43. 1.407.1

    23 Jul 2026

    Reading the note…

  44. 1.407.0

    22 Jul 2026

    Reading the note…

  45. 1.406.2

    21 Jul 2026

    Reading the note…

  46. 1.406.1

    21 Jul 2026

    Reading the note…

  47. 1.406.0

    21 Jul 2026

    Reading the note…

  48. 1.405.3

    21 Jul 2026

    Reading the note…

  49. 1.405.2

    20 Jul 2026

    Reading the note…

  50. 1.405.1

    20 Jul 2026

    Reading the note…