Packages

rrweb-snapshot

2.2.0 · 24 Oct 2026MIT4.1M / weekRepositoryHomepagenpmAtom feed

Your version

2.0.0

major1 Jun 2026Where it was published

2.2.0 is the newest release of 2.x.

In short

4 breaking13 new2 faster53 fixed

  • breaking

    Thanks @Juice10 & @rotemreiss! - Require rrweb-snapshot.rebuild() to use a trusted sandboxed iframe document by default.

  • breaking

    Distributed files have new filenames, paths and extensions. Important: If you reference distributed files or types directly, you might have to update your paths/filenames. E.g. you import from rrweb/typings/... or rrdom/es. However you run import rrweb from 'rrweb' you won't notice a difference with this change. If you include rrweb files directly in a script tag, you might have to update that path to include a the .umd.cjs files instead. All .js files now use ES modules which can be used in modern browsers, node.js and bundlers that support ES modules. All npm packages now also ship .cjs and .umd.cjs files. The .umd.cjs files are CommonJS modules that bundle all files together to make it easy to ship one file to browser environments (similar to the previous .js files). The .cjs files are CommonJS modules that can be used in older Node.js environments. Types should be better defined in package.json and if you need specific types they might be exported from new packages (for example PlayerMachineState and SpeedMachineState are now exported from @rrweb/replay). Check the package.json's main and exports field for the available files.

  • breaking

    NodeType enum was moved from rrweb-snapshot to @rrweb/types The following types where moved from rrweb-snapshot to @rrweb/types: documentNode, documentTypeNode, legacyAttributes, textNode, cdataNode, commentNode, elementNode, serializedNode, serializedNodeWithId, serializedElementNodeWithId, serializedTextNodeWithId, IMirror, INode, mediaAttributes, attributes and DataURLOptions

  • breaking

    Remove INode / node.__sn usage and use Mirror as the source of truth.

Release note

Breaking Change upgrading from 2.0.0-alpha.X

We shipped a defensive security measure which breaks backwards compatibility in code using the rrweb-snapshot package directly (rrweb or rrweb-replay package users don't need to make any changes). rebuild() now refuses to rebuild into an unprotected browser document if we can't guarantee a safe sandboxed environment. More details below, and thanks for the report from @rotemreiss.

Major Changes

  • breaking

    Thanks @Juice10 & @rotemreiss! - Require rrweb-snapshot.rebuild() to use a trusted sandboxed iframe document by default.

    New function rebuildIntoSandboxedIframe() adds a safe sandboxed iframe environment, preventing untrusted DOM snapshots from escaping their iframe and executing malicious code. If you need to manage the iframe separately, you can create it with createSandboxedIframe() before calling rebuild().

    In cases where the recorded DOM is 100% trusted or running in a clean environment without meaningful escape risk - for example, a throwaway Playwright-style environment or code recorded from a test suite on CI - we've added an explicit escape hatch: pass UNSAFE_allowUnprotectedRebuild: true to rebuild().

    rrweb now marks UNSAFE_replayCanvas rebuilds as an explicit unsafe path because canvas replay adds script permission to the replay iframe.

  • breaking

    Distributed files have new filenames, paths and extensions. Important: If you reference distributed files or types directly, you might have to update your paths/filenames. E.g. you import from rrweb/typings/... or rrdom/es. However you run import rrweb from 'rrweb' you won't notice a difference with this change. If you include rrweb files directly in a script tag, you might have to update that path to include a the .umd.cjs files instead. All .js files now use ES modules which can be used in modern browsers, node.js and bundlers that support ES modules. All npm packages now also ship .cjs and .umd.cjs files. The .umd.cjs files are CommonJS modules that bundle all files together to make it easy to ship one file to browser environments (similar to the previous .js files). The .cjs files are CommonJS modules that can be used in older Node.js environments. Types should be better defined in package.json and if you need specific types they might be exported from new packages (for example PlayerMachineState and SpeedMachineState are now exported from @rrweb/replay). Check the package.json's main and exports field for the available files.

  • breaking

    NodeType enum was moved from rrweb-snapshot to @rrweb/types
    The following types where moved from rrweb-snapshot to @rrweb/types: documentNode, documentTypeNode, legacyAttributes, textNode, cdataNode, commentNode, elementNode, serializedNode, serializedNodeWithId, serializedElementNodeWithId, serializedTextNodeWithId, IMirror, INode, mediaAttributes, attributes and DataURLOptions

  • breaking

    Remove INode / node.__sn usage and use Mirror as the source of truth.

Minor Changes

  • Video and Audio elements now also capture playbackRate, muted, loop, volume.

  • Record dialog's modal status for replay in rrweb. (Currently triggering dialog.showModal() is not supported in rrweb-snapshot's rebuild)

  • Extends maskInputFn to pass the HTMLElement to the deciding function

  • Ensure password inputs remain masked when switching input type

  • Ignore autoplay attribute on video/audio elements

  • Extends maskTextFn to pass the HTMLElement to the deciding function

  • Add support for cross-origin iframe recording, including event/id remapping and genId export support.

  • Add support for recording and replaying constructable adoptedStyleSheets, including stylesheet mutations, replace/replaceSync, shadow roots, iframes, live mode, and virtual DOM replay.

  • Add the fast-forward virtual DOM optimization for replay.

Patch Changes

  • Handle exceptions thrown from postcss when calling adaptCssForReplay

  • Fix that the optional maskInputFn was being accidentally ignored during the creation of the full snapshot

  • Duplicate textContent for style elements cause incremental style mutations to be invalid

  • Drop base64 inlined worker source from all bundles

  • Extend to run fixBrowserCompatibilityIssuesInCSS over inline stylesheets

  • Improve performance of splitCssText for <style> elements with large css content - see #1603

  • Improve performance of splitCssText for <style> elements with large css content - see #1603

  • Better support for coexistence with older libraries (e.g. MooTools & Prototype.js) which modify the in-built Array.from function

  • Fix and test for bug #1457 which was affecting replay of complex tailwind css

  • Fixup for multiple background-clip replacement

  • Fix that postcss could fall over when trying to process css content split arbitrarily

  • CSS transitions are incorrectly being applied upon rebuild in Firefox. Presumably FF doesn't finished parsing the styles in time, and applies e.g. a default margin:0 to elements which have a non-zero margin set in CSS, along with a transition on them.

    Related bug report to Firefox: bugzilla.mozilla.org/show_bug.cgi

  • Avoid recreating the same element every time, instead, we cache and we just update the element.

    Before: 779k ops/s
    After: 860k ops/s

    Benchmark: jsbench.me/ktlqztuf95/1

  • inlineImages: During snapshot avoid adding an event listener for inlining of same-origin images (async listener mutates the snapshot which can be problematic)

  • Upgrade all projects to typescript 4.9.5

  • Make relative path detection in stylesheet URLs to detect more types of URL protocols when inlining stylesheets.

  • Fix duplicated shadow doms

  • Ensure attributes are lowercased when checking

  • Use ownerNode.baseURI for stringifying sheet hrefs

  • Better nested css selector splitting when commas or brackets happen to be in quoted text

  • Bugfix after #1434 perf improvements: fix that blob urls persist on the shared anchor element and can't be later modified

  • Avoid creation of intermediary array when iterating over style rules

  • Refactor all suffix of bundled scripts with commonjs module from 'js' to cjs #1087.

  • Replay: Replace negative lookbehind in regexes from css parser as it causes issues with Safari 16

  • Fix dimensions for blocked element not being applied

  • Improve: Add try catch to snapshot.ts 's masking text function. Fixes #1118.

  • (when recordCanvas: true): ensure we use doc.createElement instead of document.createElement to allow use in non-browser e.g. jsdom environments

  • Don't double-record the values of <textarea>s when they already have some content prefilled #1301

  • Tree-shake replay-only postcss code from the @rrweb/record bundle.

  • Fix css parsing errors

  • Add workaround for Chrome/Edge CSS @import escaping bug: bugs.chromium.org/p/chromium/issues/detail

  • Ensure :hover works on replayer, even if a rule is behind a media query
    Respect the intent behind max-device-width and min-device-width media queries so that their effects are apparent in the replayer context

  • Change to ignore all link[rel="modulepreload"] instead of including only those with as="script"

  • Slight simplification to how we replace :hover after #1458

  • Edge case: Provide support for mutations on a <style> element which (unusually) has multiple text nodes

  • Fix url() rewrite for nested stylesheets by rewriting during stringification instead of after

  • optimisation: Skip mask check on leaf elements

  • #1172 don't replace original onload function of Images

  • Add 'isCustom' flag to serialized elements.

    This flag is used to indicate whether the element is a custom element or not. This is useful for replaying the :defined pseudo-class of custom elements.

  • Capture stylesheets designated as rel="preload"

  • Fix missing import after #1705

  • Explicitly handle null attribute values

  • Snapshot performance when masking text: Avoid the repeated calls to closest when recursing through the DOM

  • Fix CSS rules captured in Safari

  • Provide a /umd/ output folder alongside the /dist/ one so that we can serve UMD (Universal Module Definition) files with a .js extension, without upsetting expectations set by package.json that all .js files in /dist/ are modules

  • Add slimDOM option to block animation on <title> tag; enabled when the 'all' value is used for slimDOM

  • Reverse monkey patch built in methods to support LWC (and other frameworks like angular which monkey patch built in methods).

  • Preserve -webkit-background-clip: text when serializing CSS rules.

  • Ensure replay plugin onBuild hooks run for newly appended mutation nodes and top-level rebuilt document nodes.

  • Fix replay of delayed inlined stylesheet links by updating the existing link/style node attributes instead of adding a child node.

  • Apply internal rr_* attributes after normal attributes so replay-only values such as rr_dataURL are not overwritten by serialized DOM attributes.

  • Fix iframe reload and rrdom diff issues by handling negative and unserialized node ids correctly.

  • Fix iframe replay failures after the second full snapshot.

  • Fix missing mutations when using slimDOMOptions by tracking ignored nodes in the mirror.

  • Fix SVG <use href="#..."> snapshot serialization so local fragment references are preserved instead of converted to absolute URLs.

  • Fix recording and replay of polyfilled Shadow DOM from ShadyDOM and @lwc/synthetic-shadow.

  • Fix fast-forward replay so canvas image data inside iframes is restored when rebuilding through the virtual DOM path.

  • Fix issue #904 in snapshot serialization.

  • Speed up snapshotting of many newly added DOM nodes.

  • Inline stylesheets when they load so late stylesheet content is captured.