From aab4c553cb22aa056c0bf63a436e9f3c7cf28a0b Mon Sep 17 00:00:00 2001 From: Justin Halsall Date: Wed, 1 Apr 2026 12:00:00 +0800 Subject: [PATCH] docs: revamp installation docs for esm and umd (#1788) * docs: revamp installation docs for esm and umd Document recommended install paths across the main guides and package READMEs for rrweb, @rrweb/all, @rrweb/record, @rrweb/replay, and rrweb-player. Clarify three usage modes: bundler/npm, browser no-build with import maps and +esm, and legacy UMD fallback. * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply formatting changes * Apply suggestion from @eoghanmurray Co-authored-by: Eoghan Murray * Apply formatting changes * docs(all): streamline README usage section Move the guide link next to the import example and remove the duplicated Usage section to keep docs concise and easier to scan. * docs(readme): update gzip size badges in zh-cn readme * docs(plugins): update readme imports to scoped esm packages Replace `rrweb` default imports and `rrweb.Replayer` usage with `@rrweb/record` `record` and `@rrweb/replay` `Replayer` in plugin usage examples. Also update canvas WebRTC plugin imports to scoped `@rrweb/*` package names to keep docs aligned with current package structure. * docs: update docs to prefer scoped esm packages replace `rrweb` default import examples with `@rrweb/record` and `@rrweb/replay` across recipes and guides in en/zh-CN. clarify package selection for new integrations, add `@rrweb/all` convenience guidance, and refresh CDN/style import snippets for ESM and legacy UMD compatibility. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Eoghan Murray --- .changeset/docs-install-guidance.md | 4 + README.zh_CN.md | 4 +- docs/recipes/canvas.md | 12 +- docs/recipes/canvas.zh_CN.md | 12 +- docs/recipes/console.md | 12 +- docs/recipes/console.zh_CN.md | 12 +- docs/recipes/cross-origin-iframes.md | 8 +- docs/recipes/cross-origin-iframes.zh_CN.md | 8 +- docs/recipes/custom-event.md | 12 +- docs/recipes/custom-event.zh_CN.md | 12 +- docs/recipes/customize-replayer.md | 6 +- docs/recipes/customize-replayer.zh_CN.md | 6 +- docs/recipes/index.md | 2 +- docs/recipes/index.zh_CN.md | 2 +- docs/recipes/interaction.md | 4 +- docs/recipes/interaction.zh_CN.md | 4 +- docs/recipes/live-mode.md | 10 +- docs/recipes/live-mode.zh_CN.md | 6 +- docs/recipes/optimize-storage.md | 13 +- docs/recipes/optimize-storage.zh_CN.md | 17 +- docs/recipes/pagination.md | 8 +- docs/recipes/pagination.zh_CN.md | 8 +- docs/recipes/plugin.md | 8 +- docs/recipes/plugin.zh_CN.md | 8 +- docs/recipes/record-and-replay.md | 10 +- docs/recipes/record-and-replay.zh_CN.md | 10 +- guide.md | 203 +++++++++++++----- guide.zh_CN.md | 200 ++++++++++++----- packages/all/README.md | 49 ++++- .../Readme.md | 12 +- .../Readme.md | 8 +- .../README.md | 4 +- .../README.md | 4 +- packages/record/README.md | 31 +++ packages/replay/README.md | 41 ++++ packages/rrweb-player/README.md | 39 +++- packages/rrweb/README.md | 75 ++++++- 37 files changed, 667 insertions(+), 217 deletions(-) create mode 100644 .changeset/docs-install-guidance.md diff --git a/.changeset/docs-install-guidance.md b/.changeset/docs-install-guidance.md new file mode 100644 index 00000000..3d681213 --- /dev/null +++ b/.changeset/docs-install-guidance.md @@ -0,0 +1,4 @@ +--- +--- + +Docs-only update: clarify package recommendation order (`@rrweb/record` + `@rrweb/replay` first, `@rrweb/all` as convenience), and fix example typos. diff --git a/README.zh_CN.md b/README.zh_CN.md index 7f250b24..4f72aec3 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -11,8 +11,8 @@ [![Join the chat at slack](https://img.shields.io/badge/slack-@rrweb-teal.svg?logo=slack)](https://join.slack.com/t/rrweb/shared_invite/zt-siwoc6hx-uWay3s2wyG8t5GpZVb8rWg) [![Reddit](https://img.shields.io/badge/reddit-r/rrweb-teal.svg?logo=reddit)](https://www.reddit.com/r/rrweb) -![total gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/rrweb@latest/umd/rrweb.min.js?compression=gzip&label=total%20gzip%20size) -![recorder gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js?compression=gzip&label=recorder%20gzip%20size) +![recorder gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js?compression=gzip&label=recorder%20gzip%20size&max=200000&softmax=100000) +![replayer gzip size](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/umd/replay.min.js?compression=gzip&label=replayer%20gzip%20size&max=200000&softmax=100000) [![](https://data.jsdelivr.com/v1/package/npm/rrweb/badge)](https://www.jsdelivr.com/package/npm/rrweb) > 我已开通 Github Sponsor, 您可以通过赞助的形式帮助 rrweb 的开发。 diff --git a/docs/recipes/canvas.md b/docs/recipes/canvas.md index d6676211..00677b83 100644 --- a/docs/recipes/canvas.md +++ b/docs/recipes/canvas.md @@ -6,7 +6,9 @@ There are some options for recording and replaying Canvas. Enable recording Canvas: ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, recordCanvas: true, }); @@ -15,7 +17,9 @@ rrweb.record({ Alternatively enable image snapshot recording of Canvas at a maximum of 15 frames per second: ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, recordCanvas: true, sampling: { @@ -32,7 +36,9 @@ rrweb.record({ Enable replaying Canvas: ```js -const replayer = new rrweb.Replayer(events, { +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events, { UNSAFE_replayCanvas: true, }); replayer.play(); diff --git a/docs/recipes/canvas.zh_CN.md b/docs/recipes/canvas.zh_CN.md index ae8902a4..175c8695 100644 --- a/docs/recipes/canvas.zh_CN.md +++ b/docs/recipes/canvas.zh_CN.md @@ -5,7 +5,9 @@ Canvas 是一种特殊的 HTML 元素,默认情况下其内容不会被 rrweb 录制时包含 Canvas 内的内容: ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, // 对 canvas 进行录制 recordCanvas: true, @@ -15,7 +17,9 @@ rrweb.record({ 或者启用每秒 15 帧的 Canvas 图像快照记录: ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, recordCanvas: true, sampling: { @@ -32,7 +36,9 @@ rrweb.record({ 回放时对 Canvas 进行回放: ```js -const replayer = new rrweb.Replayer(events, { +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events, { UNSAFE_replayCanvas: true, }); replayer.play(); diff --git a/docs/recipes/console.md b/docs/recipes/console.md index eb7b9a15..ccc67848 100644 --- a/docs/recipes/console.md +++ b/docs/recipes/console.md @@ -8,10 +8,10 @@ This feature aims to provide developers with more information about the bug scen You can enable the logger using default option like this: ```js -import rrweb from 'rrweb'; +import { record } from '@rrweb/record'; import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record'; -rrweb.record({ +record({ emit: function emit(event) { // you should use console.log in this way to avoid errors. const defaultLog = console.log['__rrweb_original__'] @@ -30,10 +30,10 @@ You should call console.log.\_\_rrweb_original\_\_() instead. You can also customize the behavior of logger like this: ```js -import rrweb from 'rrweb'; +import { record } from '@rrweb/record'; import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record'; -rrweb.record({ +record({ emit: function emit(event) { // you should use console.log in this way to avoid errors. const defaultLog = console.log['__rrweb_original__'] @@ -70,10 +70,10 @@ All options are described below: If recorded events include data of console log type, we will automatically play them. ```js -import rrweb from 'rrweb'; +import { Replayer } from '@rrweb/replay'; import { getReplayConsolePlugin } from '@rrweb/rrweb-plugin-console-replay'; -const replayer = new rrweb.Replayer(events, { +const replayer = new Replayer(events, { plugins: [ getReplayConsolePlugin({ level: ['info', 'log', 'warn', 'error'], diff --git a/docs/recipes/console.zh_CN.md b/docs/recipes/console.zh_CN.md index 42d0c08c..fdbfdc60 100644 --- a/docs/recipes/console.zh_CN.md +++ b/docs/recipes/console.zh_CN.md @@ -7,10 +7,10 @@ 可以通过如下代码使用默认的配置选项 ```js -import rrweb from 'rrweb'; +import { record } from '@rrweb/record'; import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record'; -rweb.record({ +record({ emit: function emit(event) { // 如果要使用console来输出信息,请使用如下的写法 const defaultLog = console.log['__rrweb_original__'] @@ -29,10 +29,10 @@ rweb.record({ 你也可以定制录制 console 的选项 ```js -import rrweb from 'rrweb'; +import { record } from '@rrweb/record'; import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record'; -rrweb.record({ +record({ emit: function emit(event) { // 如果要使用console来输出信息,请使用如下的写法 const defaultLog = console.log['__rrweb_original__'] @@ -69,10 +69,10 @@ rrweb.record({ 如果 replayer 传入的 events 中包含了 console 类型的数据,我们将自动播放这些数据。 ```js -import rrweb from 'rrweb'; +import { Replayer } from '@rrweb/replay'; import { getReplayConsolePlugin } from '@rrweb/rrweb-plugin-console-replay'; -const replayer = new rrweb.Replayer(events, { +const replayer = new Replayer(events, { plugins: [ getReplayConsolePlugin({ level: ['info', 'log', 'warn', 'error'], diff --git a/docs/recipes/cross-origin-iframes.md b/docs/recipes/cross-origin-iframes.md index 89c01dee..f945d642 100644 --- a/docs/recipes/cross-origin-iframes.md +++ b/docs/recipes/cross-origin-iframes.md @@ -8,7 +8,9 @@ Since if you allow recording cross origin iframes, any malicious website can emb Enable recording cross-origin iframes in your parent page: ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, // all events will be emitted here, including events from cross origin iframes recordCrossOriginIframes: true, }); @@ -17,7 +19,9 @@ rrweb.record({ Enable replaying cross-origin iframes in your child page: ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, // this is required for rrweb, but the child page will not emit any events recordCrossOriginIframes: true, }); diff --git a/docs/recipes/cross-origin-iframes.zh_CN.md b/docs/recipes/cross-origin-iframes.zh_CN.md index b56f9542..c0d1397b 100644 --- a/docs/recipes/cross-origin-iframes.zh_CN.md +++ b/docs/recipes/cross-origin-iframes.zh_CN.md @@ -8,7 +8,9 @@ 在父页面中启用录制跨域 iframe: ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, // 所有事件都将在此处发出,包括来自跨源 iframe 的事件 recordCrossOriginIframes: true, }); @@ -17,7 +19,9 @@ rrweb.record({ 在您的子页面中启用重放跨域 iframe: ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, // 这是 rrweb 所必需的,但子页面不会发出任何事件 recordCrossOriginIframes: true, }); diff --git a/docs/recipes/custom-event.md b/docs/recipes/custom-event.md index 287b8e7d..105876d9 100644 --- a/docs/recipes/custom-event.md +++ b/docs/recipes/custom-event.md @@ -5,19 +5,21 @@ You may need to record some custom events along with the rrweb events, and let t After starting the recording, we can call the `record.addCustomEvent` API to add a custom event. ```js +import { record } from '@rrweb/record'; + // start recording -rrweb.record({ +record({ emit(event) { ... } }) // record some custom events at any time -rrweb.record.addCustomEvent('submit-form', { +record.addCustomEvent('submit-form', { name: 'Adam', age: 18 }) -rrweb.record.addCustomEvent('some-error', { +record.addCustomEvent('some-error', { error }) ``` @@ -29,7 +31,9 @@ During the replay, we can add an event listener to custom events, or configure t **Listen to custom events** ```js -const replayer = new rrweb.Replayer(events); +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events); replayer.on('custom-event', (event) => { console.log(event.tag, event.payload); diff --git a/docs/recipes/custom-event.zh_CN.md b/docs/recipes/custom-event.zh_CN.md index 388d48ce..47f6e2be 100644 --- a/docs/recipes/custom-event.zh_CN.md +++ b/docs/recipes/custom-event.zh_CN.md @@ -5,19 +5,21 @@ 开始录制后,我们就可以通过 `record.addCustomEvent` API 添加自定义事件: ```js +import { record } from '@rrweb/record'; + // 开始录制 -rrweb.record({ +record({ emit(event) { ... } }) // 在开始录制后的任意时间点记录自定义事件,例如: -rrweb.record.addCustomEvent('submit-form', { +record.addCustomEvent('submit-form', { name: '姓名', age: 18 }) -rrweb.record.addCustomEvent('some-error', { +record.addCustomEvent('some-error', { error }) ``` @@ -29,7 +31,9 @@ rrweb.record.addCustomEvent('some-error', { **获取对应事件** ```js -const replayer = new rrweb.Replayer(events); +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events); replayer.on('custom-event', (event) => { console.log(event.tag, event.payload); diff --git a/docs/recipes/customize-replayer.md b/docs/recipes/customize-replayer.md index 218ced24..5f9570f5 100644 --- a/docs/recipes/customize-replayer.md +++ b/docs/recipes/customize-replayer.md @@ -1,13 +1,13 @@ # Customize the Replayer -When rrweb's Replayer and the [rrweb-player](../../packages/rrweb-player/) UI do not fit your need, you can customize your replayer UI. +When `Replayer` and the [rrweb-player](../../packages/rrweb-player/) UI do not fit your need, you can customize your replayer UI. There are several ways to do this: 1. Use [rrweb-player](../../packages/rrweb-player/), and customize its CSS. 2. Use [rrweb-player](../../packages/rrweb-player/), and set `showController: false` to hide the controller UI. With this config, you can implement your controller UI. 3. Use the `insertStyleRules` options to inject some CSS into the replay iframe. -4. Develop a new replayer UI with rrweb's Replayer. +4. Develop a new replayer UI with `Replayer`. ## Implement Your Controller UI @@ -69,6 +69,6 @@ rrwebPlayer.addEventListener('ui-update-progress', (event) => { }); ``` -## Develop a new replayer UI with rrweb's Replayer. +## Develop a new replayer UI with `Replayer`. Please refer [rrweb-player](https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-player/). diff --git a/docs/recipes/customize-replayer.zh_CN.md b/docs/recipes/customize-replayer.zh_CN.md index 70a29730..7142b81e 100644 --- a/docs/recipes/customize-replayer.zh_CN.md +++ b/docs/recipes/customize-replayer.zh_CN.md @@ -1,13 +1,13 @@ # 自定义回放 UI -当 rrweb Replayer 和 [rrweb-player](../../packages/rrweb-player/) 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。 +当 `Replayer` 和 [rrweb-player](../../packages/rrweb-player/) 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。 你可以通过以下几种方式从不同角度自定义回放 UI: 1. 使用 [rrweb-player](../../packages/rrweb-player/) 时,通过覆盖 CSS 样式表定制 UI。 2. 使用 [rrweb-player](../../packages/rrweb-player/) 时,通过 `showController: false` 隐藏控制器 UI,重新实现控制器 UI。 3. 通过 `insertStyleRules` 在回放页面(iframe)内定制 CSS 样式。 -4. 基于 rrweb Replayer 开发自己的回放器 UI。 +4. 基于 `Replayer` 开发自己的回放器 UI。 ## 实现控制器 UI @@ -69,6 +69,6 @@ rrwebPlayer.addEventListener('ui-update-progress', (event) => { }); ``` -## 基于 rrweb Replayer 开发自己的回放器 UI +## 基于 `Replayer` 开发自己的回放器 UI 可以参照 [rrweb-player](https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-player/) 的方式进行开发。 diff --git a/docs/recipes/index.md b/docs/recipes/index.md index 0a542606..6f5c71d5 100644 --- a/docs/recipes/index.md +++ b/docs/recipes/index.md @@ -42,7 +42,7 @@ By default, the UI could not interact during replay. But you can use API to enab ### Customize The Replayer -When rrweb's Replayer and the rrweb-player UI do not fit your need, you can customize your own replayer UI. +When `Replayer` and the rrweb-player UI do not fit your need, you can customize your own replayer UI. [link](./customize-replayer.md) diff --git a/docs/recipes/index.zh_CN.md b/docs/recipes/index.zh_CN.md index 708965a9..1aa735c2 100644 --- a/docs/recipes/index.zh_CN.md +++ b/docs/recipes/index.zh_CN.md @@ -42,7 +42,7 @@ ### 自定义回放 UI -当 rrweb Replayer 和 rrweb-player 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。 +当 `Replayer` 和 rrweb-player 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。 [链接](./customize-replayer.zh_CN.md) diff --git a/docs/recipes/interaction.md b/docs/recipes/interaction.md index b2d8e9c5..d9f45433 100644 --- a/docs/recipes/interaction.md +++ b/docs/recipes/interaction.md @@ -3,7 +3,9 @@ By default, the UI could not interact during replay. But you can use API to enable/disable this programmatically. ```js -const replayer = new rrweb.Replayer(events); +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events); // enable user interact with the UI replayer.enableInteract(); diff --git a/docs/recipes/interaction.zh_CN.md b/docs/recipes/interaction.zh_CN.md index 9a054125..509545f5 100644 --- a/docs/recipes/interaction.zh_CN.md +++ b/docs/recipes/interaction.zh_CN.md @@ -3,7 +3,9 @@ 回放时的 UI 默认不可交互,但在特定场景下也可以通过 API 允许用户与回放场景进行交互。 ```js -const replayer = new rrweb.Replayer(events); +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events); // 允许用户在回放的 UI 中进行交互 replayer.enableInteract(); diff --git a/docs/recipes/live-mode.md b/docs/recipes/live-mode.md index 8d60f7b7..0f14195e 100644 --- a/docs/recipes/live-mode.md +++ b/docs/recipes/live-mode.md @@ -2,10 +2,12 @@ If you want to replay the events in a real-time way, you can use the live mode API. This API is also useful for some real-time collaboration usage. -When you are using rrweb's Replayer to do a real-time replay, you need to configure `liveMode: true` and call the `startLive` API to enable the live mode. +When you use `Replayer` for real-time replay, configure `liveMode: true` and call `startLive()` to enable live mode. ```js -const replayer = new rrweb.Replayer([], { +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer([], { liveMode: true, }); replayer.startLive(); @@ -22,7 +24,9 @@ function onReceive(event) { If you have an ongoing recording that already has events, and wish to initiate play from a 'live' time, it's also possible to use the `play` function, supplied with an offset which corresponds to the current time: ```js -const replayer = new rrweb.Replayer(EXISTING_EVENTS, { +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(EXISTING_EVENTS, { liveMode: true, }); replayer.play(Date.now() - EXISTING_EVENTS[0].timestamp); diff --git a/docs/recipes/live-mode.zh_CN.md b/docs/recipes/live-mode.zh_CN.md index a2c6c206..2766db82 100644 --- a/docs/recipes/live-mode.zh_CN.md +++ b/docs/recipes/live-mode.zh_CN.md @@ -2,10 +2,12 @@ 如果希望持续、实时地看到录制的数据,达到类似直播的效果,则可以使用实时回放 API。这个方式也适用于一些实时协同的场景。 -使用 rrweb Replayer 进行实时回放时,需要传入 `liveMode: true` 配置,并通过 `startLive` API 启动直播模式。 +使用 `Replayer` 进行实时回放时,需要传入 `liveMode: true` 配置,并通过 `startLive` API 启动直播模式。 ```js -const replayer = new rrweb.Replayer([], { +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer([], { liveMode: true, }); diff --git a/docs/recipes/optimize-storage.md b/docs/recipes/optimize-storage.md index 9a67d103..9b658137 100644 --- a/docs/recipes/optimize-storage.md +++ b/docs/recipes/optimize-storage.md @@ -26,7 +26,9 @@ Use the sampling config in the recording can reduce the storage size by dropping **Scenario 1** ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, sampling: { // do not record mouse movement @@ -46,7 +48,9 @@ rrweb.record({ **Scenario 2** ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, sampling: { // Configure which kinds of mouse interaction should be recorded @@ -76,7 +80,7 @@ You can use it by passing it as the `packFn` in the recording. ```js import { pack } from '@rrweb/packer'; -rrweb.record({ +record({ emit(event) {}, packFn: pack, }); @@ -86,8 +90,9 @@ And you need to pass packer.unpack as the `unpackFn` in replaying. ```js import { unpack } from '@rrweb/packer'; +import { Replayer } from '@rrweb/replay'; -const replayer = new rrweb.Replayer(events, { +const replayer = new Replayer(events, { unpackFn: unpack, }); ``` diff --git a/docs/recipes/optimize-storage.zh_CN.md b/docs/recipes/optimize-storage.zh_CN.md index 92bbdbdb..181fe4fd 100644 --- a/docs/recipes/optimize-storage.zh_CN.md +++ b/docs/recipes/optimize-storage.zh_CN.md @@ -26,7 +26,9 @@ **示例 1** ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, sampling: { // 不录制鼠标移动事件 @@ -46,7 +48,9 @@ rrweb.record({ **示例 2** ```js -rrweb.record({ +import { record } from '@rrweb/record'; + +record({ emit(event) {}, sampling: { // 定义不录制的鼠标交互事件类型,可以细粒度的开启或关闭对应交互录制 @@ -74,9 +78,9 @@ rrweb 提供了一个基于 fflate 的简单压缩函数,在 [@rrweb/packer](. ```js import { pack } from '@rrweb/packer'; -rrweb.record({ +record({ emit(event) {}, - packFn: rrweb.pack, + packFn: pack, }); ``` @@ -84,9 +88,10 @@ rrweb.record({ ```js import { unpack } from '@rrweb/packer'; +import { Replayer } from '@rrweb/replay'; -const replayer = new rrweb.Replayer(events, { - unpackFn: rrweb.unpack, +const replayer = new Replayer(events, { + unpackFn: unpack, }); ``` diff --git a/docs/recipes/pagination.md b/docs/recipes/pagination.md index 7b439c8a..87f41c09 100644 --- a/docs/recipes/pagination.md +++ b/docs/recipes/pagination.md @@ -5,7 +5,9 @@ When the size of the recorded events increased, load them in one request is not rrweb's API for loading async events is quite simple: ```js -const replayer = new rrweb.Replayer(events); +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events); replayer.addEvent(NEW_EVENT); ``` @@ -15,7 +17,9 @@ When calling the `addEvent` API to add a new event, rrweb will resolve its times If you need to load several events, you can do a loop like this: ```js -const replayer = new rrweb.Replayer(events); +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events); for (const event of NEW_EVENTS) { replayer.addEvent(event); diff --git a/docs/recipes/pagination.zh_CN.md b/docs/recipes/pagination.zh_CN.md index 92d5ed1e..5da70045 100644 --- a/docs/recipes/pagination.zh_CN.md +++ b/docs/recipes/pagination.zh_CN.md @@ -5,7 +5,9 @@ rrweb 中用于实现异步加载数据的 API 非常简单直观: ```js -const replayer = new rrweb.Replayer(events); +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events); replayer.addEvent(NEW_EVENT); ``` @@ -15,7 +17,9 @@ replayer.addEvent(NEW_EVENT); 如果需要异步加载多个数据,只需这样使用: ```js -const replayer = new rrweb.Replayer(events); +import { Replayer } from '@rrweb/replay'; + +const replayer = new Replayer(events); for (const event of NEW_EVENTS) { replayer.addEvent(event); diff --git a/docs/recipes/plugin.md b/docs/recipes/plugin.md index d322bc1e..0ffbba6f 100644 --- a/docs/recipes/plugin.md +++ b/docs/recipes/plugin.md @@ -38,6 +38,8 @@ Both record and replay plugins have a type interface. #### record plugin ```ts +import { record } from '@rrweb/record'; + const exampleRecordPlugin: RecordPlugin<{ foo: string }> = { name: 'my-scope/example@1', observer(cb, options) { @@ -54,7 +56,7 @@ const exampleRecordPlugin: RecordPlugin<{ foo: string }> = { }, }; -rrweb.record({ +record({ emit: emit(event) {}, plugins: [exampleRecordPlugin], }); @@ -79,6 +81,8 @@ In this example, the record plugin will emit events like this: #### replay plugin ```ts +import { Replayer } from '@rrweb/replay'; + const exampleReplayPlugin: ReplayPlugin = { handler(event, isSync, context) { if (event.type === EventType.Plugin) { @@ -90,7 +94,7 @@ const exampleReplayPlugin: ReplayPlugin = { }, }; -const replayer = new rrweb.Replayer(events, { +const replayer = new Replayer(events, { plugins: [exampleReplayPlugin], }); ``` diff --git a/docs/recipes/plugin.zh_CN.md b/docs/recipes/plugin.zh_CN.md index 806e4e22..d95e753e 100644 --- a/docs/recipes/plugin.zh_CN.md +++ b/docs/recipes/plugin.zh_CN.md @@ -38,6 +38,8 @@ export type ReplayPlugin = { #### 录制侧插件 ```ts +import { record } from '@rrweb/record'; + const exampleRecordPlugin: RecordPlugin<{ foo: string }> = { name: 'my-scope/example@1', observer(cb, options) { @@ -54,7 +56,7 @@ const exampleRecordPlugin: RecordPlugin<{ foo: string }> = { }, }; -rrweb.record({ +record({ emit: emit(event) {}, plugins: [exampleRecordPlugin], }); @@ -79,6 +81,8 @@ rrweb.record({ #### 回放侧插件 ```ts +import { Replayer } from '@rrweb/replay'; + const exampleReplayPlugin: ReplayPlugin = { handler(event, isSync, context) { if (event.type === EventType.Plugin) { @@ -90,7 +94,7 @@ const exampleReplayPlugin: ReplayPlugin = { }, }; -const replayer = new rrweb.Replayer(events, { +const replayer = new Replayer(events, { plugins: [exampleReplayPlugin], }); ``` diff --git a/docs/recipes/record-and-replay.md b/docs/recipes/record-and-replay.md index 7b4b77bb..f1d64c2d 100644 --- a/docs/recipes/record-and-replay.md +++ b/docs/recipes/record-and-replay.md @@ -5,7 +5,9 @@ Record and Replay is the most common use case, which is suitable for any scenari You only need a simple API call to record the website: ```js -const stopFn = rrweb.record({ +import { record } from '@rrweb/record'; + +const stopFn = record({ emit(event) { // save the event }, @@ -21,11 +23,13 @@ But you should guarantee: You can use the `stopFn` to stop the recording. -The replay is also as simple as putting events into rrweb's Replayer. +Replay is also as simple as passing events into `Replayer`. ```js +import { Replayer } from '@rrweb/replay'; + const events = GET_YOUR_EVENTS; -const replayer = new rrweb.Replayer(events); +const replayer = new Replayer(events); replayer.play(); ``` diff --git a/docs/recipes/record-and-replay.zh_CN.md b/docs/recipes/record-and-replay.zh_CN.md index 6661cffb..2c916765 100644 --- a/docs/recipes/record-and-replay.zh_CN.md +++ b/docs/recipes/record-and-replay.zh_CN.md @@ -5,7 +5,9 @@ 仅需一个函数调用就可以录制当前页面: ```js -const stopFn = rrweb.record({ +import { record } from '@rrweb/record'; + +const stopFn = record({ emit(event) { // 保存获取到的 event 数据 }, @@ -19,11 +21,13 @@ const stopFn = rrweb.record({ 如果需要手动停止录制,可以调用返回的 `stopFn` 函数。 -回放时只需要获取一段录制数据,并传入 rrweb 提供的 Replayer: +回放时只需要获取一段录制数据,并传入 `Replayer`: ```js +import { Replayer } from '@rrweb/replay'; + const events = GET_YOUR_EVENTS; -const replayer = new rrweb.Replayer(events); +const replayer = new Replayer(events); replayer.play(); ``` diff --git a/guide.md b/guide.md index 96727a49..53418fae 100644 --- a/guide.md +++ b/guide.md @@ -6,57 +6,119 @@ ## Installation -### Direct ` +### 1) Bundler / npm (Recommended) + +```shell +npm install @rrweb/record @rrweb/replay ``` -Also, you can link to a specific version number that you can update manually: - -```html - +```js +import { record } from '@rrweb/record'; +import { Replayer } from '@rrweb/replay'; +import '@rrweb/replay/dist/style.css'; ``` -#### Only include the recorder code +Use `@rrweb/all` as a convenience package if you want a single import: -rrweb's code includes both the record and the replay parts. Most of the time you only need to include the record part into your targeted web Apps. -This also can be done by using the `@rrweb/record` package and the CDN service: - -```html - +```shell +npm install @rrweb/all ``` -The recorder UMD build exposes a global named `rrwebRecord`. +```js +import { record, Replayer } from '@rrweb/all'; +import '@rrweb/all/dist/style.css'; +``` -#### Only include the replayer code +`require(...)` / CommonJS remains available for compatibility via each package's `exports`/`main`, but ESM imports are the primary path for 2.x. + +### 2) Browser Without Bundler (No-Build) + +Use ES modules and import maps with jsDelivr `+esm`: ```html - + + ``` -The replayer UMD build exposes a global named `rrwebReplay`. +Or use `@rrweb/all` as a convenience browser ESM import: + +```html + + + +``` + +### 3) Legacy Direct ` +``` + +The UMD build exposes global `rrweb`. + +Legacy single-purpose UMD bundles: + +```html + + +``` + +The UMD globals are `rrwebRecord` and `rrwebReplay`. #### Other packages -Besides the `rrweb` and `@rrweb/record` packages, rrweb also provides other packages for different usage. +Besides the `@rrweb/record` and `@rrweb/replay` packages, rrweb also provides other packages for different usage. - [rrweb](packages/rrweb): The core package of rrweb, including record and replay functions. - [rrweb-player](packages/rrweb-player): A GUI for rrweb, providing a timeline and buttons for things like pause, fast-forward, and speedup. - [rrweb-snapshot](packages/rrweb-snapshot): Handles snapshot and rebuilding features, converting the DOM and its state into a serializable data structure. - [rrdom](packages/rrdom): A virtual dom package rrweb. - [rrdom-nodejs](packages/rrdom-nodejs): The Node.js version of rrdom for server-side DOM operations. -- [@rrweb/all](packages/all): A package that includes `rrweb` and `@rrweb/packer` for easy install. +- [@rrweb/all](packages/all): A convenience package that includes `rrweb` and `@rrweb/packer`. - [@rrweb/record](packages/record): A package for recording rrweb sessions. - [@rrweb/replay](packages/replay): A package for replaying rrweb sessions. - [@rrweb/packer](packages/packer): A package for packing and unpacking rrweb data. @@ -71,14 +133,6 @@ Besides the `rrweb` and `@rrweb/record` packages, rrweb also provides other pack - [@rrweb/rrweb-plugin-canvas-webrtc-record](packages/plugins/rrweb-plugin-canvas-webrtc-record): A plugin for stream `` via WebRTC. - [@rrweb/rrweb-plugin-canvas-webrtc-replay](packages/plugins/rrweb-plugin-canvas-webrtc-replay): A plugin for playing streamed `` via WebRTC. -### NPM - -```shell -npm install --save rrweb -``` - -rrweb provides both commonJS and ES modules bundles, which are easy to use with the popular bundlers. - ### Compatibility Note rrweb does **not** support IE11 and below because it uses the `MutationObserver` API which was supported by [these browsers](https://caniuse.com/#feat=mutationobserver). @@ -87,10 +141,14 @@ rrweb does **not** support IE11 and below because it uses the `MutationObserver` ### Record -The following sample code will use the variable `rrweb` which is the default exporter of this library. +Use `record` from `@rrweb/record` in modern setups: ```js -rrweb.record({ +import { record } from '@rrweb/record'; +``` + +```js +record({ emit(event) { // store the event in any way you like }, @@ -102,7 +160,7 @@ During recording, the recorder will emit when there is some event incurred, all The `record` method returns a function which can be called to stop events from firing: ```js -let stopFn = rrweb.record({ +let stopFn = record({ emit(event) { if (events.length > 100) { // stop after 100 events @@ -117,7 +175,7 @@ A more real-world usage may look like this: ```js let events = []; -rrweb.record({ +record({ emit(event) { // push event into the events array events.push(event); @@ -143,7 +201,7 @@ setInterval(save, 10 * 1000); #### Options -The parameter of `rrweb.record` accepts the following options. +The `record` function accepts the following options. | key | default | description | | ------------------------ | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -196,7 +254,7 @@ By default, all the emitted events are required to replay a session and if you d // We use a two-dimensional array to store multiple events array const eventsMatrix = [[]]; -rrweb.record({ +record({ emit(event, isCheckout) { // isCheckout is a flag to tell you the events has been checkout if (isCheckout) { @@ -231,7 +289,7 @@ Similarly, you can also configure `checkoutEveryNms` to capture the last N minut // We use a two-dimensional array to store multiple events array const eventsMatrix = [[]]; -rrweb.record({ +record({ emit(event, isCheckout) { // isCheckout is a flag to tell you the events has been checkout if (isCheckout) { @@ -262,28 +320,36 @@ With the sample code above, you will finally get the last 5 to 10 minutes of eve ### Replay -You need to include the style sheet before replay: +For bundler usage, include the style sheet in your app entry: + +```js +import '@rrweb/replay/dist/style.css'; +``` + +For browser/no-build usage, include the style sheet in HTML: ```html ``` -And then initialize the replayer with the following code: +And then initialize the replayer: ```js +import { Replayer } from '@rrweb/replay'; + const events = YOUR_EVENTS; -const replayer = new rrweb.Replayer(events); +const replayer = new Replayer(events); replayer.play(); ``` #### Control the replayer by API ```js -const replayer = new rrweb.Replayer(events); +const replayer = new Replayer(events); // play replayer.play(); @@ -329,29 +395,48 @@ The replayer accepts options as its constructor's second parameter, and it has t #### Use rrweb-player -Since rrweb's replayer ([@rrweb/replay](packages/replay/)) only provides a basic UI, you can choose [rrweb-player](packages/rrweb-player/) which is based on rrweb's public APIs but has a feature-rich replayer UI. +Since `Replayer` from [@rrweb/replay](packages/replay/) only provides a basic UI, you can choose [rrweb-player](packages/rrweb-player/), which is based on rrweb's public APIs and provides a feature-rich replayer UI. ##### Installation -rrweb-player can also be included with ` + + ``` -Or installed by using NPM: +Legacy direct ` ``` ##### Usage @@ -377,15 +462,15 @@ new rrwebPlayer({ | speedOption | [1, 2, 4, 8] | speed options in UI | | showController | true | whether to show the controller UI | | tags | {} | customize the custom events style with a key-value map | -| ... | - | all the rrweb Replayer options will be bypassed | +| ... | - | all other Replayer options are forwarded | #### Events -Developers may want to extend the rrweb's replayer or respond to its events. Such as giving notification when the replayer starts to skip inactive time. -So rrweb expose a public API `on` which allow developers to listen to the events and customize the reactions, and it has the following events: +Developers may want to extend the replayer or respond to its events, for example to notify users when inactive time starts being skipped. +`Replayer` exposes a public API `on` that lets developers listen for events and customize behavior: ```js -const replayer = new rrweb.Replayer(events); +const replayer = new Replayer(events); replayer.on(EVENT_NAME, (payload) => { ... }) diff --git a/guide.zh_CN.md b/guide.zh_CN.md index 8786e03a..76a608a6 100644 --- a/guide.zh_CN.md +++ b/guide.zh_CN.md @@ -4,56 +4,119 @@ ## 安装 -### 直接通过 ` +### 1) Bundler / npm(推荐) + +```shell +npm install @rrweb/record @rrweb/replay ``` -也可以在 URL 中指定具体的版本号,例如: - -```html - +```js +import { record } from '@rrweb/record'; +import { Replayer } from '@rrweb/replay'; +import '@rrweb/replay/dist/style.css'; ``` -#### 仅引入录制部分 +如果你希望使用单一入口,也可以使用便捷包 `@rrweb/all`: -rrweb 代码分为录制和回放两部分,大多数时候用户在被录制的应用中只需要引入录制部分代码。同样可以通过使用 @rrweb/record 包和 CDN 服务来实现: - -```html - +```shell +npm install @rrweb/all ``` -录制端的 UMD build 会暴露全局变量 `rrwebRecord`。 +```js +import { record, Replayer } from '@rrweb/all'; +import '@rrweb/all/dist/style.css'; +``` -#### 仅引入回放部分 +`require(...)` / CommonJS 仍可作为兼容方案使用(由各包的 `exports`/`main` 提供),但 2.x 的主路径是 ESM。 + +### 2) 无 Bundler 的浏览器场景(推荐 no-build) + +推荐使用 ES modules + import map + jsDelivr `+esm`: ```html - + + ``` -回放端的 UMD build 会暴露全局变量 `rrwebReplay`。 +也可以通过 `@rrweb/all` 便捷引入: + +```html + + + +``` + +### 3) 传统直接 ` +``` + +该 UMD 构建会暴露全局变量 `rrweb`。 + +仅录制 / 仅回放的 UMD 兼容包: + +```html + + +``` + +对应全局变量分别是 `rrwebRecord` 和 `rrwebReplay`。 #### 其他包 -除了 `rrweb` 和 `@rrweb/record` 包之外,rrweb 还提供了其他不同用途的包。 +除了 `@rrweb/record` 和 `@rrweb/replay` 包之外,rrweb 还提供了其他不同用途的包。 - [rrweb](packages/rrweb):rrweb 的核心包,包括录制和回放功能。 - [rrweb-player](packages/rrweb-player):rrweb 的图形用户界面,提供时间线和暂停、快进、加速等按钮。 - [rrweb-snapshot](packages/rrweb-snapshot):处理快照和重建功能,将 DOM 及其状态转换为可序列化的数据结构。 - [rrdom](packages/rrdom):rrweb 的虚拟 dom 包。 - [rrdom-nodejs](packages/rrdom-nodejs):用于服务器端 DOM 操作的 rrdom 的 Node.js 版本。 -- [@rrweb/all](packages/all):一个包含 `rrweb` 和 `@rrweb/packer`,便于安装的包。 +- [@rrweb/all](packages/all):一个包含 `rrweb` 和 `@rrweb/packer` 的便捷包。 - [@rrweb/record](packages/record):一个用于录制 rrweb 会话的包。 - [@rrweb/replay](packages/replay):一个用于回放 rrweb 会话的包。 - [@rrweb/packer](packages/packer):一个用于打包和解包 rrweb 数据的包。 @@ -68,14 +131,6 @@ rrweb 代码分为录制和回放两部分,大多数时候用户在被录制 - [@rrweb/rrweb-plugin-canvas-webrtc-record](packages/plugins/rrweb-plugin-canvas-webrtc-record):一个用于通过 WebRTC 流式传输 `` 的插件。 - [@rrweb/rrweb-plugin-canvas-webrtc-replay](packages/plugins/rrweb-plugin-canvas-webrtc-replay):一个用于通过 WebRTC 播放流式 `` 的插件。 -### 通过 npm 引入 - -```shell -npm install --save rrweb -``` - -rrweb 同时提供 commonJS 和 ES modules 两种格式的打包文件,易于和常见的打包工具配合使用。 - ### 兼容性 由于使用 `MutationObserver` API,rrweb 不支持 IE11 以下的浏览器。可以从[这里](https://caniuse.com/#feat=mutationobserver)找到兼容的浏览器列表。 @@ -84,10 +139,14 @@ rrweb 同时提供 commonJS 和 ES modules 两种格式的打包文件,易于 ### 录制 -如果通过 ` + + ``` -或者通过 npm 安装: +Legacy 直接 ` ``` ##### 使用 @@ -373,16 +459,16 @@ new rrwebPlayer({ | speedOption | [1, 2, 4, 8] | 倍速播放可选值 | | showController | true | 是否显示播放器控制 UI | | tags | {} | 可以以 key value 的形式展示自定义事件在时间轴上的颜色 | -| ... | - | 其它所有 rrweb Replayer 的配置参数均可透传 | +| ... | - | 其它所有 Replayer 的配置参数均可透传 | #### 事件 开发者可能希望监听回放时的各类事件,例如在跳过无用户操作的时间时给用户一些提示。 -rrweb 的 Replayer 提供了 `on` API 用于提供该功能 +Replayer 提供了 `on` API 用于实现该功能 ```js -const replayer = new rrweb.Replayer(events); +const replayer = new Replayer(events); replayer.on(EVENT_NAME, (payload) => { ... }) diff --git a/packages/all/README.md b/packages/all/README.md index d71a5653..b3d87b34 100644 --- a/packages/all/README.md +++ b/packages/all/README.md @@ -1,6 +1,15 @@ # @rrweb/all Convenience package that includes a bundle of rrweb packages. +For most new integrations, prefer `@rrweb/record` + `@rrweb/replay` first, and use `@rrweb/all` when you want a single-package setup. + +| Use case | Package choice | +| --------------------------------------------------- | --------------------------------- | +| Most new apps (explicit record/replay dependencies) | `@rrweb/record` + `@rrweb/replay` | +| Quick setup with one import | `@rrweb/all` | +| Legacy compatibility | `rrweb` | + +In most production setups, recorder and replayer are deployed to different pages/apps. Use `@rrweb/record` on recorded pages and `@rrweb/replay` (or `rrweb-player`) on replay pages. Use `@rrweb/all` when you intentionally want one package for convenience (for example demos, tooling, or simplified setups). Includes the following packages: @@ -11,19 +20,47 @@ Includes the following packages: ## Installation +### 1) Bundler / npm + ```bash npm install @rrweb/all ``` -## Usage - ```js -import { record, replay, pack, unpack } from '@rrweb/all'; - -// use record, replay, pack, unpack as you would with the individual packages. +import { record, Replayer, pack, unpack } from '@rrweb/all'; +import '@rrweb/all/dist/style.css'; ``` -See the [guide](../../guide.md) for more info on rrweb. +For API details and examples, see the [guide](../../guide.md). + +### 2) Browser Without Bundler (ESM + import maps) + +```html + + + +``` + +### 3) Legacy Direct ` +``` + +The legacy UMD global is `rrweb`, so you will need to prefix the example APIs, e.g. `rrweb.record`, `new rrweb.Replayer(...)`, `rrweb.pack`, and `rrweb.unpack`, rather than using these functions directly. ## Sponsors diff --git a/packages/plugins/rrweb-plugin-canvas-webrtc-record/Readme.md b/packages/plugins/rrweb-plugin-canvas-webrtc-record/Readme.md index 520da44c..a0243d0a 100644 --- a/packages/plugins/rrweb-plugin-canvas-webrtc-record/Readme.md +++ b/packages/plugins/rrweb-plugin-canvas-webrtc-record/Readme.md @@ -13,8 +13,8 @@ https://user-images.githubusercontent.com/4106/186701616-fd71a107-5d53-423c-ba09 ```js // Record side -import rrweb from 'rrweb'; -import { RRWebPluginCanvasWebRTCRecord } from 'rrweb-plugin-canvas-webrtc-record'; +import { record } from '@rrweb/record'; +import { RRWebPluginCanvasWebRTCRecord } from '@rrweb/rrweb-plugin-canvas-webrtc-record'; const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({ signalSendCallback: (msg) => { @@ -24,7 +24,7 @@ const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({ }, }); -rrweb.record({ +record({ emit: (event) => { // send these events to the `replayer.addEvent(event)`, how you do that is up to you // you can send them to a server for example which can then send them to the replayer @@ -42,8 +42,8 @@ rrweb.record({ ```js // Replay side -import rrweb from 'rrweb'; -import { RRWebPluginCanvasWebRTCReplay } from 'rrweb-plugin-canvas-webrtc-replay'; +import { Replayer } from '@rrweb/replay'; +import { RRWebPluginCanvasWebRTCReplay } from '@rrweb/rrweb-plugin-canvas-webrtc-replay'; const webRTCReplayPlugin = new RRWebPluginCanvasWebRTCReplay({ canvasFoundCallback(canvas, context) { @@ -59,7 +59,7 @@ const webRTCReplayPlugin = new RRWebPluginCanvasWebRTCReplay({ }, }); -const replayer = new rrweb.Replayer([], { +const replayer = new Replayer([], { UNSAFE_replayCanvas: true, // turn canvas replay on! liveMode: true, // live mode is needed to stream events to the replayer plugins: [webRTCReplayPlugin.initPlugin()], diff --git a/packages/plugins/rrweb-plugin-canvas-webrtc-replay/Readme.md b/packages/plugins/rrweb-plugin-canvas-webrtc-replay/Readme.md index fcc6a725..95f4b565 100644 --- a/packages/plugins/rrweb-plugin-canvas-webrtc-replay/Readme.md +++ b/packages/plugins/rrweb-plugin-canvas-webrtc-replay/Readme.md @@ -13,7 +13,7 @@ https://user-images.githubusercontent.com/4106/186701616-fd71a107-5d53-423c-ba09 ```js // Record side -import rrweb from 'rrweb'; +import { record } from '@rrweb/record'; import { RRWebPluginCanvasWebRTCRecord } from '@rrweb/rrweb-plugin-canvas-webrtc-record'; const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({ @@ -24,7 +24,7 @@ const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({ }, }); -rrweb.record({ +record({ emit: (event) => { // send these events to the `replayer.addEvent(event)`, how you do that is up to you // you can send them to a server for example which can then send them to the replayer @@ -42,7 +42,7 @@ rrweb.record({ ```js // Replay side -import rrweb from 'rrweb'; +import { Replayer } from '@rrweb/replay'; import { RRWebPluginCanvasWebRTCReplay } from '@rrweb/rrweb-plugin-canvas-webrtc-replay'; const webRTCReplayPlugin = new RRWebPluginCanvasWebRTCReplay({ @@ -59,7 +59,7 @@ const webRTCReplayPlugin = new RRWebPluginCanvasWebRTCReplay({ }, }); -const replayer = new rrweb.Replayer([], { +const replayer = new Replayer([], { UNSAFE_replayCanvas: true, // turn canvas replay on! liveMode: true, // live mode is needed to stream events to the replayer plugins: [webRTCReplayPlugin.initPlugin()], diff --git a/packages/plugins/rrweb-plugin-sequential-id-record/README.md b/packages/plugins/rrweb-plugin-sequential-id-record/README.md index 9d36ba38..068e80f8 100644 --- a/packages/plugins/rrweb-plugin-sequential-id-record/README.md +++ b/packages/plugins/rrweb-plugin-sequential-id-record/README.md @@ -12,10 +12,10 @@ npm install @rrweb/rrweb-plugin-sequential-id-record ## Usage ```js -import rrweb from 'rrweb'; +import { record } from '@rrweb/record'; import { getRecordSequentialIdPlugin } from '@rrweb/rrweb-plugin-sequential-id-record'; -rrweb.record({ +record({ emit: function emit(event) { // send events to server }, diff --git a/packages/plugins/rrweb-plugin-sequential-id-replay/README.md b/packages/plugins/rrweb-plugin-sequential-id-replay/README.md index 29e27202..311cc154 100644 --- a/packages/plugins/rrweb-plugin-sequential-id-replay/README.md +++ b/packages/plugins/rrweb-plugin-sequential-id-replay/README.md @@ -12,10 +12,10 @@ npm install @rrweb/rrweb-plugin-sequential-id-replay ## Usage ```js -import rrweb from 'rrweb'; +import { Replayer } from '@rrweb/replay'; import { getReplaySequentialIdPlugin } from '@rrweb/rrweb-plugin-sequential-id-replay'; -const replayer = new rrweb.Replayer(events, { +const replayer = new Replayer(events, { plugins: [ getReplaySequentialIdPlugin({ // make sure this is the same as the record side diff --git a/packages/record/README.md b/packages/record/README.md index 7c448e7b..d3326685 100644 --- a/packages/record/README.md +++ b/packages/record/README.md @@ -5,10 +5,41 @@ See the [guide](../../guide.md) for more info on rrweb. ## Installation +### 1) Bundler / npm (Recommended) + ```bash npm install @rrweb/record ``` +```js +import { record } from '@rrweb/record'; +``` + +### 2) Browser Without Bundler (ESM + import maps) + +```html + + +``` + +### 3) Legacy Direct ` +``` + +The legacy UMD global is `rrwebRecord`. + ## Usage ```js diff --git a/packages/replay/README.md b/packages/replay/README.md index de3ff891..007205dd 100644 --- a/packages/replay/README.md +++ b/packages/replay/README.md @@ -5,14 +5,55 @@ See the [guide](../../guide.md) for more info on rrweb. ## Installation +### 1) Bundler / npm (Recommended) + ```bash npm install @rrweb/replay ``` +```js +import { Replayer } from '@rrweb/replay'; +import '@rrweb/replay/dist/style.css'; +``` + +### 2) Browser Without Bundler (ESM + import maps) + +```html + + + +``` + +### 3) Legacy Direct ` +``` + +The legacy UMD global is `rrwebReplay`. + ## Usage ```js import { Replayer } from '@rrweb/replay'; +import '@rrweb/replay/dist/style.css'; const replayer = new Replayer(events, { // options diff --git a/packages/rrweb-player/README.md b/packages/rrweb-player/README.md index 15fcf4c8..51ce73fe 100644 --- a/packages/rrweb-player/README.md +++ b/packages/rrweb-player/README.md @@ -12,25 +12,46 @@ rrweb-player uses rrweb's Replayer under the hood, but as Replayer doesn't inclu ## Installation -rrweb-player can also be included with ` + + ``` -Or installed by using NPM: +### 3) Legacy Direct ` ``` ## Usage diff --git a/packages/rrweb/README.md b/packages/rrweb/README.md index 4e14cef4..3e738a19 100644 --- a/packages/rrweb/README.md +++ b/packages/rrweb/README.md @@ -19,12 +19,85 @@ rrweb refers to 'record and replay the web', which is a tool for recording and r [**🍳 Recipes 🍳**](../../docs/recipes/index.md) +## Installation + +`rrweb` is kept mainly for backward compatibility. For new integrations, prefer package-specific entrypoints (`@rrweb/record` and `@rrweb/replay`) first, or use `@rrweb/all` as a convenience package. + +### 1) Bundler / npm (Recommended) + +For new projects: + +```shell +npm install @rrweb/record @rrweb/replay +``` + +```js +import { record } from '@rrweb/record'; +import { Replayer } from '@rrweb/replay'; +import '@rrweb/replay/dist/style.css'; +``` + +Convenience single-package option: + +```shell +npm install @rrweb/all +``` + +```js +import { record, Replayer, pack, unpack } from '@rrweb/all'; +import '@rrweb/all/dist/style.css'; +``` + +Legacy compatibility package: + +```shell +npm install rrweb +``` + +```js +import { record, Replayer } from 'rrweb'; +import 'rrweb/dist/style.css'; +``` + +### 2) Browser Without Bundler (ESM + import maps) + +```html + + + +``` + +### 3) Legacy Direct ` +``` + ## Project Structure **[rrweb](https://github.com/rrweb-io/rrweb)** mainly includes two funtions: - **Record**: The record function is used to record all the mutations in the DOM -- **Replay**: The replay function is to replay the recorded mutations one by one according to the corresponding timestamp. +- **Replayer**: The replay function is to replay the recorded mutations one by one according to the corresponding timestamp. ## Roadmap