rrweb
2.2.0 · 24 Oct 2026MIT4.2M / weekRepositoryHomepagenpmAtom feed
2.2.0 is the newest release of 2.x.
In short
5 breaking1 deprecated24 new7 faster98 fixed6 internal
- breaking
Split plugins out of rrweb and move them into their own packages: @rrweb/packer, @rrweb/rrweb-plugin-canvas-webrtc-record, @rrweb/rrweb-plugin-canvas-webrtc-replay, @rrweb/rrweb-plugin-sequential-id-record, @rrweb/rrweb-plugin-sequential-id-replay, @rrweb/rrweb-plugin-console-record, @rrweb/rrweb-plugin-console-replay. Check out the README of each package for more information or check out #1033 to see the changes.
- 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/...orrrdom/es. However you runimport 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.cjsfiles instead. All.jsfiles 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.cjsand.umd.cjsfiles. The.umd.cjsfiles are CommonJS modules that bundle all files together to make it easy to ship one file to browser environments (similar to the previous.jsfiles). The.cjsfiles are CommonJS modules that can be used in older Node.js environments. Types should be better defined inpackage.jsonand if you need specific types they might be exported from new packages (for examplePlayerMachineStateandSpeedMachineStateare now exported from@rrweb/replay). Check thepackage.json'smainandexportsfield for the available files. - breaking
Move shared rrweb event and recorder types into the new
@rrweb/typespackage. - breaking
Remove
INode/node.__snusage and useMirroras the source of truth. - breaking
Move browser-only rrdom features into the new
rrdompackage. - deprecated
Mark
inlineImagesandinlineStylesheetrecord options as deprecated in docs and public types while preserving existing behavior.
Release note
Major Changes
- breaking
Split plugins out of rrweb and move them into their own packages: @rrweb/packer, @rrweb/rrweb-plugin-canvas-webrtc-record, @rrweb/rrweb-plugin-canvas-webrtc-replay, @rrweb/rrweb-plugin-sequential-id-record, @rrweb/rrweb-plugin-sequential-id-replay, @rrweb/rrweb-plugin-console-record, @rrweb/rrweb-plugin-console-replay. Check out the README of each package for more information or check out #1033 to see the changes.
- 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/...orrrdom/es. However you runimport 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.cjsfiles instead. All.jsfiles 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.cjsand.umd.cjsfiles. The.umd.cjsfiles are CommonJS modules that bundle all files together to make it easy to ship one file to browser environments (similar to the previous.jsfiles). The.cjsfiles are CommonJS modules that can be used in older Node.js environments. Types should be better defined inpackage.jsonand if you need specific types they might be exported from new packages (for examplePlayerMachineStateandSpeedMachineStateare now exported from@rrweb/replay). Check thepackage.json'smainandexportsfield for the available files. - breaking
Remove the rrweb-all.js, rrweb-record.js, and rrweb-replay.js files from
rrwebpackage. Now you can use@rrweb/all,@rrweb/record, and@rrweb/replaypackages instead. Check out the README of each package for more information or check out PR #1033 to see the changes. - breaking
Move shared rrweb event and recorder types into the new
@rrweb/typespackage. - breaking
Remove
INode/node.__snusage and useMirroras the source of truth. - breaking
Move browser-only rrdom features into the new
rrdompackage.
Minor Changes
Click events now include a
.pointerTypeattribute which distinguishes between 'pen', 'mouse' and 'touch' events. There is no new PenDown/PenUp events, but these can be detected with a MouseDown/MouseUp + pointerType=penFull overhawl of
videoandaudioelement playback. More robust and fixes lots of bugs related to pausing/playing/skipping/muting/playbackRate etc.Extends maskInputFn to pass the HTMLElement to the deciding function
Ensure password inputs remain masked when switching input type
Allow to pass
errorHandleras record optionSupport top-layer <dialog> components. Fixes #1381.
Extends maskTextFn to pass the HTMLElement to the deciding function
Optimize isParentRemoved check
Add support for recording cross-origin iframes via
recordCrossOriginIframes.Add support for recording and replaying constructable
adoptedStyleSheets, including stylesheet mutations,replace/replaceSync, shadow roots, iframes, live mode, and virtual DOM replay.Add recording and replay support for text selection events.
Add a
destroy()method to fully remove a replayer instance and emit a destroy event.Add canvas WebRTC record and replay plugins for live-streaming canvas contents.
Add support for recording and replaying media
playbackRatechanges.Add
dataURLOptionsto control canvas snapshot image format and quality.Add
ignoreCSSAttributesand applyblockSelectorchecks consistently across recorder observers.Add support for recording canvas snapshots at a configured FPS.
Add the fast-forward virtual DOM optimization for replay.
Patch Changes
Don't include redundant data from text/attribute mutations on just-added nodes
Fix that the optional
maskInputFnwas being accidentally ignored during the creation of the full snapshotcreateImageBitmap throws DOMException if source is 0 width or height
Safely capture BigInt values with the console log plugin"
Fix checking for
patchTargetininitAdoptedStyleSheetObserverFix the statement which is getting changed by Microbundle
Compact style mutation fixes and improvements
fixes when style updates contain a 'var()' on a shorthand property #1246
further ensures that style mutations are compact by reverting to string method if it is shorter
Add
ignoreSelectoroptionSimilar to ignoreClass, but accepts a CSS selector so that you can use any CSS selector.
Reset the finished flag in Controller
gotoinstead ofhandleProgressClickso that it is properly handled ifgotois called directly.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
Guard against presence of older 3rd party javascript libraries which redefine Date.now()
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
Switch from virtual dom to real dom before rebuilding fullsnapshot
Export
ReplayPluginfrom rrweb directly. Previously we had to doimport type { ReplayPlugin } from 'rrweb/dist/types';now we can doimport type { ReplayPlugin } from 'rrweb';Better support for coexistence with older libraries (e.g. MooTools & Prototype.js) which modify the in-built
Array.fromfunctionAvoid an extra function call and object clone during event emission
Fix and test for bug #1457 which was affecting replay of complex tailwind css
#1178 remove warning related to worker_threads while building
Fixup for multiple background-clip replacement
Fix that postcss could fall over when trying to process css content split arbitrarily
Add support for replaying :defined pseudo-class of custom elements
processed-node-manager is created even in the environment that doesn't need a recorder
Export takeFullSnapshot function for a recording process
Optimize performance of the DoubleLinkedList get
Added support for deprecated addRule & removeRule methods
- deprecated
Mark
inlineImagesandinlineStylesheetrecord options as deprecated in docs and public types while preserving existing behavior. 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
Move patch function into @rrweb/utils to improve bundling
Optimize performance of isParentRemoved by converting it to an iterative procedure
Make relative path detection in stylesheet URLs to detect more types of URL protocols when inlining stylesheets.
Export the canvasMutation function
Export eventWithTime for consumption by typescript code
Guard against redefinition of Date.now by third party libraries which are also present on a page alongside rrweb
Fix duplicated shadow doms
Ensure attributes are lowercased when checking
Optimize the performance of record in processMutation phase
Use WeakMap for faster attributeCursor lookup while processing attribute mutations
Rrweb recorder may throw error when stopping recording after an iframe becomes cross-origin
Resize and MediaInteraction events repeat generated after the iframe appeared
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.
Ensure getting the type of inputs works
Replay: Replace negative lookbehind in regexes from css parser as it causes issues with Safari 16
Add 'recordDOM' config option to turn off recording of DOM (making recordings unreplayable). Specialist use case e.g. only heatmap click/scroll recording
For a mutation which removes a node, reduce the number of spurious warnings to take into account that an anscestor (rather than just a parent) may have been just removed
Some nested cross-origin iframes can't be recorded
Improve nested CSS rule handling and replayer handling of missing rules
Don't double-record the values of <textarea>s when they already have some content prefilled #1301
Improve rrdom robustness #1091.
Tree-shake replay-only
postcsscode from the@rrweb/recordbundle.This fixes an issue where inlined CSS from a remotely loaded
<link>does not get applied properly due to object reference mutation.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 contextRequire browser
rebuild()calls to target a document created byrebuildIntoSandboxedIframe()orcreateSandboxedIframe()by default. Use these helpers for untrusted replay data, or passUNSAFE_allowUnprotectedRebuild: trueonly when accepting the script-execution risk.rrwebnow marksUNSAFE_replayCanvasrebuilds as an explicit unsafe path because canvas replay adds script permission to the replay iframe.Refactor to preclude the need for a continuous raf loop running in the background which is related to shadowDom
Change to ignore all link[rel="modulepreload"] instead of including only those with
as="script"Return early for child same origin frames
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
Only apply touch-active styling on flush
optimisation: Skip mask check on leaf elements
Record
loopon<audio>&<video>elements.Capture stylesheets designated as
rel="preload"NodeTypeenum 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,attributesandDataURLOptionsisCheckout is missed in all fullsnapshot events
Explicitly handle
nullattribute valuesAdd masking for innerText mutations on textarea elements
Snapshot performance when masking text: Avoid the repeated calls to
closestwhen recursing through the DOMProvide 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
Protect against missing parentNode
Outdated ':hover' styles can't be removed from iframes or shadow doms
Handle case where
eventis null/undefinedCanvas FPS recording: override
preserveDrawingBuffer: trueon canvas creation.
Canvas replay: fix flickering canvas elemenrs.
Canvas FPS recording: fix bug that wipes webgl(2) canvas backgrounds while recording.Add slimDOM option to block animation on <title> tag; enabled when the 'all' value is used for slimDOM
Add missing change logs manually. In the next version, all change logs will be generated automatically.
#1053 Thanks @Juice10! - Fix: Post message can break cross origin iframe recording.
#1063 Thanks @lele0108! - Fix: muted false -> true not being set.
#1042 Thanks @wfk007! - Fix: Failed to execute insertBefore on Node.
#1058 Thanks @mydea! - Handle errors when observing iframes.
#1083 Thanks @Juice10! - Fix: Catch iframe manager & fix formatting issues.
#1083 Thanks @eoghanmurray! - Harmonize on a single getWindowScroll
#1086 Thanks @YunFeng0817! - Fix: missed adopted style sheets of shadow doms in checkout full snapshot.
#1032 Thanks @dbseel! - Fix: isBlocked throws on invalid HTML element.
#1088 Thanks @mydea! - Fix: Guard against missing window.CSSStyleSheet.
#1093 Thanks @YunFeng0817! - Fix: cross origin iframe bugs.
#1104 Thanks @jlalmes! - [console-plugin] Feat: Record unhandled rejection event.
#1115 Thanks @Juice10! - Fix: Don't trigger Finish event when in liveMode.
#1106 Thanks @mydea! - Fix: Ensure CSS support is checked more robustly.
#1100 Thanks @YunFeng0817! - Fix: wrong rootId value in special iframes.
#1098 Thanks @eoghanmurray! - Refactor: Don't have requestAnimationFrame looping in background for Live Mode.
#1092 Thanks @YunFeng0817! - Fix: regression of issue: ShadowHost can't be a string (issue 941)
#1111 Thanks @YunFeng0817! - Feat: enable to customize logger in the replayer.
#1109 Thanks @YunFeng0817! - Feat: add option to record on DOMContentLoaded event.
#1112 Thanks @YunFeng0817! - Fix: mutation Failed to execute 'insertBefore' on 'Node': Only one doctype on document allowed.
#1119 Thanks @Juice10! - Feat: Automate NPM package releases.
Reverse monkey patch built in methods to support LWC (and other frameworks like angular which monkey patch built in methods).
aaabdbdThanks @benjackwhite! - fix: Recursive logging bug with console recordingTrigger mouse movement and hover with mouse up and mouse down events when replayer.pause(...) is called.
Wujie monkeypatches ownerDocument
Some websites rebuild imcomplete
Some websites, addedSet in emit function is not empty, but the result converted from Array.from is empty.
Some websites polyfill classList functions of HTML elements. Their implementation may throw errors and cause the snapshot to fail. I add try-catch statements to make the code robust.
For users of userTriggeredOnInput setting: also set userTriggered to false on Input attribute modifications; this was previously empty this variant of IncrementalSource.Input
Fix replaying element scroll positions when both
scrollTopandscrollLeftare applied.Use the correct document when registering shadow roots inside iframes.
Fix shadow DOM mutation handling that could enter an infinite loop on some pages.
Fix custom events and full snapshots after stopping and restarting recording.
Fix recorder crashes when non-shadow-root nodes expose a
hostproperty.Avoid recording noisy read-only WebGL properties such as
isContextLost.Fix WebGL variable tracking when multiple contexts are patched.
Ensure replay plugin
onBuildhooks 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.
Fix iframe reload and rrdom diff issues by handling negative and unserialized node ids correctly.
Fix errors when replaying selection events during fast-forward playback.
Fix FPS-based canvas recording when
blockClassis a regular expression.Fix recording of multiple children inside a shadow root.
Fix input hooks inside iframes by using the iframe document's own window prototypes.
Fix replay timing for mouse move events with empty or missing positions.
Fix recorder restart behavior by resetting internal record functions when recording stops.
Fix duplicate shadow DOM recording by avoiding repeated observation of the same shadow root.
Fix live mode timer setup to reuse the configured speed and live mode settings.
Fix
addActionso replay actions added after timer startup take effect without stopping and restarting.Fix SVG
<use href="#...">snapshot serialization so local fragment references are preserved instead of converted to absolute URLs.Fix console plugin recording so
undefinedvalues are serialized and replay correctly.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 a mutation edge case when a blocked element class is later unblocked.
Fix issue #890 in replay/recording behavior.
Apply only the latest queued text mutation for better replay behavior and performance.
Speed up snapshotting of many newly added DOM nodes.
Inline stylesheets when they load so late stylesheet content is captured.