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 <eoghan@getthere.ie> * 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 <eoghan@getthere.ie>
This commit is contained in:
4
.changeset/docs-install-guidance.md
Normal file
4
.changeset/docs-install-guidance.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
Docs-only update: clarify package recommendation order (`@rrweb/record` + `@rrweb/replay` first, `@rrweb/all` as convenience), and fix example typos.
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
[](https://join.slack.com/t/rrweb/shared_invite/zt-siwoc6hx-uWay3s2wyG8t5GpZVb8rWg)
|
[](https://join.slack.com/t/rrweb/shared_invite/zt-siwoc6hx-uWay3s2wyG8t5GpZVb8rWg)
|
||||||
[](https://www.reddit.com/r/rrweb)
|
[](https://www.reddit.com/r/rrweb)
|
||||||

|

|
||||||

|

|
||||||
[](https://www.jsdelivr.com/package/npm/rrweb)
|
[](https://www.jsdelivr.com/package/npm/rrweb)
|
||||||
|
|
||||||
> 我已开通 Github Sponsor, 您可以通过赞助的形式帮助 rrweb 的开发。
|
> 我已开通 Github Sponsor, 您可以通过赞助的形式帮助 rrweb 的开发。
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ There are some options for recording and replaying Canvas.
|
|||||||
Enable recording Canvas:
|
Enable recording Canvas:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
recordCanvas: true,
|
recordCanvas: true,
|
||||||
});
|
});
|
||||||
@@ -15,7 +17,9 @@ rrweb.record({
|
|||||||
Alternatively enable image snapshot recording of Canvas at a maximum of 15 frames per second:
|
Alternatively enable image snapshot recording of Canvas at a maximum of 15 frames per second:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
recordCanvas: true,
|
recordCanvas: true,
|
||||||
sampling: {
|
sampling: {
|
||||||
@@ -32,7 +36,9 @@ rrweb.record({
|
|||||||
Enable replaying Canvas:
|
Enable replaying Canvas:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events, {
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events, {
|
||||||
UNSAFE_replayCanvas: true,
|
UNSAFE_replayCanvas: true,
|
||||||
});
|
});
|
||||||
replayer.play();
|
replayer.play();
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ Canvas 是一种特殊的 HTML 元素,默认情况下其内容不会被 rrweb
|
|||||||
录制时包含 Canvas 内的内容:
|
录制时包含 Canvas 内的内容:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
// 对 canvas 进行录制
|
// 对 canvas 进行录制
|
||||||
recordCanvas: true,
|
recordCanvas: true,
|
||||||
@@ -15,7 +17,9 @@ rrweb.record({
|
|||||||
或者启用每秒 15 帧的 Canvas 图像快照记录:
|
或者启用每秒 15 帧的 Canvas 图像快照记录:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
recordCanvas: true,
|
recordCanvas: true,
|
||||||
sampling: {
|
sampling: {
|
||||||
@@ -32,7 +36,9 @@ rrweb.record({
|
|||||||
回放时对 Canvas 进行回放:
|
回放时对 Canvas 进行回放:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events, {
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events, {
|
||||||
UNSAFE_replayCanvas: true,
|
UNSAFE_replayCanvas: true,
|
||||||
});
|
});
|
||||||
replayer.play();
|
replayer.play();
|
||||||
|
|||||||
@@ -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:
|
You can enable the logger using default option like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import rrweb from 'rrweb';
|
import { record } from '@rrweb/record';
|
||||||
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit: function emit(event) {
|
emit: function emit(event) {
|
||||||
// you should use console.log in this way to avoid errors.
|
// you should use console.log in this way to avoid errors.
|
||||||
const defaultLog = console.log['__rrweb_original__']
|
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:
|
You can also customize the behavior of logger like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import rrweb from 'rrweb';
|
import { record } from '@rrweb/record';
|
||||||
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit: function emit(event) {
|
emit: function emit(event) {
|
||||||
// you should use console.log in this way to avoid errors.
|
// you should use console.log in this way to avoid errors.
|
||||||
const defaultLog = console.log['__rrweb_original__']
|
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.
|
If recorded events include data of console log type, we will automatically play them.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import rrweb from 'rrweb';
|
import { Replayer } from '@rrweb/replay';
|
||||||
import { getReplayConsolePlugin } from '@rrweb/rrweb-plugin-console-replay';
|
import { getReplayConsolePlugin } from '@rrweb/rrweb-plugin-console-replay';
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events, {
|
const replayer = new Replayer(events, {
|
||||||
plugins: [
|
plugins: [
|
||||||
getReplayConsolePlugin({
|
getReplayConsolePlugin({
|
||||||
level: ['info', 'log', 'warn', 'error'],
|
level: ['info', 'log', 'warn', 'error'],
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
可以通过如下代码使用默认的配置选项
|
可以通过如下代码使用默认的配置选项
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import rrweb from 'rrweb';
|
import { record } from '@rrweb/record';
|
||||||
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
||||||
|
|
||||||
rweb.record({
|
record({
|
||||||
emit: function emit(event) {
|
emit: function emit(event) {
|
||||||
// 如果要使用console来输出信息,请使用如下的写法
|
// 如果要使用console来输出信息,请使用如下的写法
|
||||||
const defaultLog = console.log['__rrweb_original__']
|
const defaultLog = console.log['__rrweb_original__']
|
||||||
@@ -29,10 +29,10 @@ rweb.record({
|
|||||||
你也可以定制录制 console 的选项
|
你也可以定制录制 console 的选项
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import rrweb from 'rrweb';
|
import { record } from '@rrweb/record';
|
||||||
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit: function emit(event) {
|
emit: function emit(event) {
|
||||||
// 如果要使用console来输出信息,请使用如下的写法
|
// 如果要使用console来输出信息,请使用如下的写法
|
||||||
const defaultLog = console.log['__rrweb_original__']
|
const defaultLog = console.log['__rrweb_original__']
|
||||||
@@ -69,10 +69,10 @@ rrweb.record({
|
|||||||
如果 replayer 传入的 events 中包含了 console 类型的数据,我们将自动播放这些数据。
|
如果 replayer 传入的 events 中包含了 console 类型的数据,我们将自动播放这些数据。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import rrweb from 'rrweb';
|
import { Replayer } from '@rrweb/replay';
|
||||||
import { getReplayConsolePlugin } from '@rrweb/rrweb-plugin-console-replay';
|
import { getReplayConsolePlugin } from '@rrweb/rrweb-plugin-console-replay';
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events, {
|
const replayer = new Replayer(events, {
|
||||||
plugins: [
|
plugins: [
|
||||||
getReplayConsolePlugin({
|
getReplayConsolePlugin({
|
||||||
level: ['info', 'log', 'warn', 'error'],
|
level: ['info', 'log', 'warn', 'error'],
|
||||||
|
|||||||
@@ -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:
|
Enable recording cross-origin iframes in your parent page:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {}, // all events will be emitted here, including events from cross origin iframes
|
emit(event) {}, // all events will be emitted here, including events from cross origin iframes
|
||||||
recordCrossOriginIframes: true,
|
recordCrossOriginIframes: true,
|
||||||
});
|
});
|
||||||
@@ -17,7 +19,9 @@ rrweb.record({
|
|||||||
Enable replaying cross-origin iframes in your child page:
|
Enable replaying cross-origin iframes in your child page:
|
||||||
|
|
||||||
```js
|
```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
|
emit(event) {}, // this is required for rrweb, but the child page will not emit any events
|
||||||
recordCrossOriginIframes: true,
|
recordCrossOriginIframes: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
在父页面中启用录制跨域 iframe:
|
在父页面中启用录制跨域 iframe:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {}, // 所有事件都将在此处发出,包括来自跨源 iframe 的事件
|
emit(event) {}, // 所有事件都将在此处发出,包括来自跨源 iframe 的事件
|
||||||
recordCrossOriginIframes: true,
|
recordCrossOriginIframes: true,
|
||||||
});
|
});
|
||||||
@@ -17,7 +19,9 @@ rrweb.record({
|
|||||||
在您的子页面中启用重放跨域 iframe:
|
在您的子页面中启用重放跨域 iframe:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {}, // 这是 rrweb 所必需的,但子页面不会发出任何事件
|
emit(event) {}, // 这是 rrweb 所必需的,但子页面不会发出任何事件
|
||||||
recordCrossOriginIframes: true,
|
recordCrossOriginIframes: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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.
|
After starting the recording, we can call the `record.addCustomEvent` API to add a custom event.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
// start recording
|
// start recording
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// record some custom events at any time
|
// record some custom events at any time
|
||||||
rrweb.record.addCustomEvent('submit-form', {
|
record.addCustomEvent('submit-form', {
|
||||||
name: 'Adam',
|
name: 'Adam',
|
||||||
age: 18
|
age: 18
|
||||||
})
|
})
|
||||||
rrweb.record.addCustomEvent('some-error', {
|
record.addCustomEvent('some-error', {
|
||||||
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**
|
**Listen to custom events**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
replayer.on('custom-event', (event) => {
|
replayer.on('custom-event', (event) => {
|
||||||
console.log(event.tag, event.payload);
|
console.log(event.tag, event.payload);
|
||||||
|
|||||||
@@ -5,19 +5,21 @@
|
|||||||
开始录制后,我们就可以通过 `record.addCustomEvent` API 添加自定义事件:
|
开始录制后,我们就可以通过 `record.addCustomEvent` API 添加自定义事件:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
// 开始录制
|
// 开始录制
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 在开始录制后的任意时间点记录自定义事件,例如:
|
// 在开始录制后的任意时间点记录自定义事件,例如:
|
||||||
rrweb.record.addCustomEvent('submit-form', {
|
record.addCustomEvent('submit-form', {
|
||||||
name: '姓名',
|
name: '姓名',
|
||||||
age: 18
|
age: 18
|
||||||
})
|
})
|
||||||
rrweb.record.addCustomEvent('some-error', {
|
record.addCustomEvent('some-error', {
|
||||||
error
|
error
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -29,7 +31,9 @@ rrweb.record.addCustomEvent('some-error', {
|
|||||||
**获取对应事件**
|
**获取对应事件**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
replayer.on('custom-event', (event) => {
|
replayer.on('custom-event', (event) => {
|
||||||
console.log(event.tag, event.payload);
|
console.log(event.tag, event.payload);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
# Customize the Replayer
|
# 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:
|
There are several ways to do this:
|
||||||
|
|
||||||
1. Use [rrweb-player](../../packages/rrweb-player/), and customize its CSS.
|
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.
|
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.
|
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
|
## 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/).
|
Please refer [rrweb-player](https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-player/).
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
# 自定义回放 UI
|
# 自定义回放 UI
|
||||||
|
|
||||||
当 rrweb Replayer 和 [rrweb-player](../../packages/rrweb-player/) 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。
|
当 `Replayer` 和 [rrweb-player](../../packages/rrweb-player/) 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。
|
||||||
|
|
||||||
你可以通过以下几种方式从不同角度自定义回放 UI:
|
你可以通过以下几种方式从不同角度自定义回放 UI:
|
||||||
|
|
||||||
1. 使用 [rrweb-player](../../packages/rrweb-player/) 时,通过覆盖 CSS 样式表定制 UI。
|
1. 使用 [rrweb-player](../../packages/rrweb-player/) 时,通过覆盖 CSS 样式表定制 UI。
|
||||||
2. 使用 [rrweb-player](../../packages/rrweb-player/) 时,通过 `showController: false` 隐藏控制器 UI,重新实现控制器 UI。
|
2. 使用 [rrweb-player](../../packages/rrweb-player/) 时,通过 `showController: false` 隐藏控制器 UI,重新实现控制器 UI。
|
||||||
3. 通过 `insertStyleRules` 在回放页面(iframe)内定制 CSS 样式。
|
3. 通过 `insertStyleRules` 在回放页面(iframe)内定制 CSS 样式。
|
||||||
4. 基于 rrweb Replayer 开发自己的回放器 UI。
|
4. 基于 `Replayer` 开发自己的回放器 UI。
|
||||||
|
|
||||||
## 实现控制器 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/) 的方式进行开发。
|
可以参照 [rrweb-player](https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-player/) 的方式进行开发。
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ By default, the UI could not interact during replay. But you can use API to enab
|
|||||||
|
|
||||||
### Customize The Replayer
|
### 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)
|
[link](./customize-replayer.md)
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
### 自定义回放 UI
|
### 自定义回放 UI
|
||||||
|
|
||||||
当 rrweb Replayer 和 rrweb-player 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。
|
当 `Replayer` 和 rrweb-player 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。
|
||||||
|
|
||||||
[链接](./customize-replayer.zh_CN.md)
|
[链接](./customize-replayer.zh_CN.md)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
By default, the UI could not interact during replay. But you can use API to enable/disable this programmatically.
|
By default, the UI could not interact during replay. But you can use API to enable/disable this programmatically.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
// enable user interact with the UI
|
// enable user interact with the UI
|
||||||
replayer.enableInteract();
|
replayer.enableInteract();
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
回放时的 UI 默认不可交互,但在特定场景下也可以通过 API 允许用户与回放场景进行交互。
|
回放时的 UI 默认不可交互,但在特定场景下也可以通过 API 允许用户与回放场景进行交互。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
// 允许用户在回放的 UI 中进行交互
|
// 允许用户在回放的 UI 中进行交互
|
||||||
replayer.enableInteract();
|
replayer.enableInteract();
|
||||||
|
|||||||
@@ -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.
|
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
|
```js
|
||||||
const replayer = new rrweb.Replayer([], {
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer([], {
|
||||||
liveMode: true,
|
liveMode: true,
|
||||||
});
|
});
|
||||||
replayer.startLive();
|
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:
|
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
|
```js
|
||||||
const replayer = new rrweb.Replayer(EXISTING_EVENTS, {
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(EXISTING_EVENTS, {
|
||||||
liveMode: true,
|
liveMode: true,
|
||||||
});
|
});
|
||||||
replayer.play(Date.now() - EXISTING_EVENTS[0].timestamp);
|
replayer.play(Date.now() - EXISTING_EVENTS[0].timestamp);
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
如果希望持续、实时地看到录制的数据,达到类似直播的效果,则可以使用实时回放 API。这个方式也适用于一些实时协同的场景。
|
如果希望持续、实时地看到录制的数据,达到类似直播的效果,则可以使用实时回放 API。这个方式也适用于一些实时协同的场景。
|
||||||
|
|
||||||
使用 rrweb Replayer 进行实时回放时,需要传入 `liveMode: true` 配置,并通过 `startLive` API 启动直播模式。
|
使用 `Replayer` 进行实时回放时,需要传入 `liveMode: true` 配置,并通过 `startLive` API 启动直播模式。
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer([], {
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer([], {
|
||||||
liveMode: true,
|
liveMode: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ Use the sampling config in the recording can reduce the storage size by dropping
|
|||||||
**Scenario 1**
|
**Scenario 1**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
sampling: {
|
sampling: {
|
||||||
// do not record mouse movement
|
// do not record mouse movement
|
||||||
@@ -46,7 +48,9 @@ rrweb.record({
|
|||||||
**Scenario 2**
|
**Scenario 2**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
sampling: {
|
sampling: {
|
||||||
// Configure which kinds of mouse interaction should be recorded
|
// 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
|
```js
|
||||||
import { pack } from '@rrweb/packer';
|
import { pack } from '@rrweb/packer';
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
packFn: pack,
|
packFn: pack,
|
||||||
});
|
});
|
||||||
@@ -86,8 +90,9 @@ And you need to pass packer.unpack as the `unpackFn` in replaying.
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
import { unpack } from '@rrweb/packer';
|
import { unpack } from '@rrweb/packer';
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events, {
|
const replayer = new Replayer(events, {
|
||||||
unpackFn: unpack,
|
unpackFn: unpack,
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
**示例 1**
|
**示例 1**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
sampling: {
|
sampling: {
|
||||||
// 不录制鼠标移动事件
|
// 不录制鼠标移动事件
|
||||||
@@ -46,7 +48,9 @@ rrweb.record({
|
|||||||
**示例 2**
|
**示例 2**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
sampling: {
|
sampling: {
|
||||||
// 定义不录制的鼠标交互事件类型,可以细粒度的开启或关闭对应交互录制
|
// 定义不录制的鼠标交互事件类型,可以细粒度的开启或关闭对应交互录制
|
||||||
@@ -74,9 +78,9 @@ rrweb 提供了一个基于 fflate 的简单压缩函数,在 [@rrweb/packer](.
|
|||||||
```js
|
```js
|
||||||
import { pack } from '@rrweb/packer';
|
import { pack } from '@rrweb/packer';
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event) {},
|
emit(event) {},
|
||||||
packFn: rrweb.pack,
|
packFn: pack,
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -84,9 +88,10 @@ rrweb.record({
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
import { unpack } from '@rrweb/packer';
|
import { unpack } from '@rrweb/packer';
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events, {
|
const replayer = new Replayer(events, {
|
||||||
unpackFn: rrweb.unpack,
|
unpackFn: unpack,
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
rrweb's API for loading async events is quite simple:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
replayer.addEvent(NEW_EVENT);
|
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:
|
If you need to load several events, you can do a loop like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
for (const event of NEW_EVENTS) {
|
for (const event of NEW_EVENTS) {
|
||||||
replayer.addEvent(event);
|
replayer.addEvent(event);
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
rrweb 中用于实现异步加载数据的 API 非常简单直观:
|
rrweb 中用于实现异步加载数据的 API 非常简单直观:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
replayer.addEvent(NEW_EVENT);
|
replayer.addEvent(NEW_EVENT);
|
||||||
```
|
```
|
||||||
@@ -15,7 +17,9 @@ replayer.addEvent(NEW_EVENT);
|
|||||||
如果需要异步加载多个数据,只需这样使用:
|
如果需要异步加载多个数据,只需这样使用:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
for (const event of NEW_EVENTS) {
|
for (const event of NEW_EVENTS) {
|
||||||
replayer.addEvent(event);
|
replayer.addEvent(event);
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ Both record and replay plugins have a type interface.
|
|||||||
#### record plugin
|
#### record plugin
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
|
const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
|
||||||
name: 'my-scope/example@1',
|
name: 'my-scope/example@1',
|
||||||
observer(cb, options) {
|
observer(cb, options) {
|
||||||
@@ -54,7 +56,7 @@ const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit: emit(event) {},
|
emit: emit(event) {},
|
||||||
plugins: [exampleRecordPlugin],
|
plugins: [exampleRecordPlugin],
|
||||||
});
|
});
|
||||||
@@ -79,6 +81,8 @@ In this example, the record plugin will emit events like this:
|
|||||||
#### replay plugin
|
#### replay plugin
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
const exampleReplayPlugin: ReplayPlugin = {
|
const exampleReplayPlugin: ReplayPlugin = {
|
||||||
handler(event, isSync, context) {
|
handler(event, isSync, context) {
|
||||||
if (event.type === EventType.Plugin) {
|
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],
|
plugins: [exampleReplayPlugin],
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ export type ReplayPlugin = {
|
|||||||
#### 录制侧插件
|
#### 录制侧插件
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
|
const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
|
||||||
name: 'my-scope/example@1',
|
name: 'my-scope/example@1',
|
||||||
observer(cb, options) {
|
observer(cb, options) {
|
||||||
@@ -54,7 +56,7 @@ const exampleRecordPlugin: RecordPlugin<{ foo: string }> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit: emit(event) {},
|
emit: emit(event) {},
|
||||||
plugins: [exampleRecordPlugin],
|
plugins: [exampleRecordPlugin],
|
||||||
});
|
});
|
||||||
@@ -79,6 +81,8 @@ rrweb.record({
|
|||||||
#### 回放侧插件
|
#### 回放侧插件
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
const exampleReplayPlugin: ReplayPlugin = {
|
const exampleReplayPlugin: ReplayPlugin = {
|
||||||
handler(event, isSync, context) {
|
handler(event, isSync, context) {
|
||||||
if (event.type === EventType.Plugin) {
|
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],
|
plugins: [exampleReplayPlugin],
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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:
|
You only need a simple API call to record the website:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const stopFn = rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
const stopFn = record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
// save the event
|
// save the event
|
||||||
},
|
},
|
||||||
@@ -21,11 +23,13 @@ But you should guarantee:
|
|||||||
|
|
||||||
You can use the `stopFn` to stop the recording.
|
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
|
```js
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
const events = GET_YOUR_EVENTS;
|
const events = GET_YOUR_EVENTS;
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new Replayer(events);
|
||||||
replayer.play();
|
replayer.play();
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
仅需一个函数调用就可以录制当前页面:
|
仅需一个函数调用就可以录制当前页面:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const stopFn = rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
const stopFn = record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
// 保存获取到的 event 数据
|
// 保存获取到的 event 数据
|
||||||
},
|
},
|
||||||
@@ -19,11 +21,13 @@ const stopFn = rrweb.record({
|
|||||||
|
|
||||||
如果需要手动停止录制,可以调用返回的 `stopFn` 函数。
|
如果需要手动停止录制,可以调用返回的 `stopFn` 函数。
|
||||||
|
|
||||||
回放时只需要获取一段录制数据,并传入 rrweb 提供的 Replayer:
|
回放时只需要获取一段录制数据,并传入 `Replayer`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
const events = GET_YOUR_EVENTS;
|
const events = GET_YOUR_EVENTS;
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new Replayer(events);
|
||||||
replayer.play();
|
replayer.play();
|
||||||
```
|
```
|
||||||
|
|||||||
207
guide.md
207
guide.md
@@ -6,57 +6,119 @@
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Direct `<script>` include
|
| Goal | Recommended package(s) |
|
||||||
|
| ------------------------------- | --------------------------------- |
|
||||||
|
| Most projects (record + replay) | `@rrweb/record` + `@rrweb/replay` |
|
||||||
|
| Single-package convenience | `@rrweb/all` |
|
||||||
|
| Legacy compatibility only | `rrweb` |
|
||||||
|
|
||||||
You are recommended to install rrweb via jsdelivr's CDN service:
|
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).
|
||||||
|
|
||||||
```html
|
### 1) Bundler / npm (Recommended)
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
```shell
|
||||||
href="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/style.css"
|
npm install @rrweb/record @rrweb/replay
|
||||||
/>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/rrweb@latest/umd/rrweb.min.js"></script>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Also, you can link to a specific version number that you can update manually:
|
```js
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
```html
|
import { Replayer } from '@rrweb/replay';
|
||||||
<script src="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.21/umd/rrweb.min.js"></script>
|
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.
|
```shell
|
||||||
This also can be done by using the `@rrweb/record` package and the CDN service:
|
npm install @rrweb/all
|
||||||
|
|
||||||
```html
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js"></script>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
```html
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
||||||
/>
|
/>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/umd/replay.min.js"></script>
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@rrweb/record": "https://cdn.jsdelivr.net/npm/@rrweb/record@latest/+esm",
|
||||||
|
"@rrweb/replay": "https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/+esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
|
emit(event) {
|
||||||
|
console.log(event);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
The replayer UMD build exposes a global named `rrwebReplay`.
|
Or use `@rrweb/all` as a convenience browser ESM import:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@rrweb/all@latest/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@rrweb/all": "https://cdn.jsdelivr.net/npm/@rrweb/all@latest/+esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { record, Replayer } from '@rrweb/all';
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Legacy Direct `<script>` Include (UMD Fallback)
|
||||||
|
|
||||||
|
Use this only for compatibility with non-module environments.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.20/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.20/umd/rrweb.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
The UMD build exposes global `rrweb`.
|
||||||
|
|
||||||
|
Legacy single-purpose UMD bundles:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@rrweb/record@2.0.0-alpha.20/umd/record.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@rrweb/replay@2.0.0-alpha.20/umd/replay.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
The UMD globals are `rrwebRecord` and `rrwebReplay`.
|
||||||
|
|
||||||
#### Other packages
|
#### 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](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-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.
|
- [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](packages/rrdom): A virtual dom package rrweb.
|
||||||
- [rrdom-nodejs](packages/rrdom-nodejs): The Node.js version of rrdom for server-side DOM operations.
|
- [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/record](packages/record): A package for recording rrweb sessions.
|
||||||
- [@rrweb/replay](packages/replay): A package for replaying rrweb sessions.
|
- [@rrweb/replay](packages/replay): A package for replaying rrweb sessions.
|
||||||
- [@rrweb/packer](packages/packer): A package for packing and unpacking rrweb data.
|
- [@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 `<canvas>` via WebRTC.
|
- [@rrweb/rrweb-plugin-canvas-webrtc-record](packages/plugins/rrweb-plugin-canvas-webrtc-record): A plugin for stream `<canvas>` via WebRTC.
|
||||||
- [@rrweb/rrweb-plugin-canvas-webrtc-replay](packages/plugins/rrweb-plugin-canvas-webrtc-replay): A plugin for playing streamed `<canvas>` via WebRTC.
|
- [@rrweb/rrweb-plugin-canvas-webrtc-replay](packages/plugins/rrweb-plugin-canvas-webrtc-replay): A plugin for playing streamed `<canvas>` 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
|
### 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).
|
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
|
### 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
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
// store the event in any way you like
|
// 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:
|
The `record` method returns a function which can be called to stop events from firing:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let stopFn = rrweb.record({
|
let stopFn = record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
if (events.length > 100) {
|
if (events.length > 100) {
|
||||||
// stop after 100 events
|
// stop after 100 events
|
||||||
@@ -117,7 +175,7 @@ A more real-world usage may look like this:
|
|||||||
```js
|
```js
|
||||||
let events = [];
|
let events = [];
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
// push event into the events array
|
// push event into the events array
|
||||||
events.push(event);
|
events.push(event);
|
||||||
@@ -143,7 +201,7 @@ setInterval(save, 10 * 1000);
|
|||||||
|
|
||||||
#### Options
|
#### Options
|
||||||
|
|
||||||
The parameter of `rrweb.record` accepts the following options.
|
The `record` function accepts the following options.
|
||||||
|
|
||||||
| key | default | description |
|
| 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
|
// We use a two-dimensional array to store multiple events array
|
||||||
const eventsMatrix = [[]];
|
const eventsMatrix = [[]];
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event, isCheckout) {
|
emit(event, isCheckout) {
|
||||||
// isCheckout is a flag to tell you the events has been checkout
|
// isCheckout is a flag to tell you the events has been checkout
|
||||||
if (isCheckout) {
|
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
|
// We use a two-dimensional array to store multiple events array
|
||||||
const eventsMatrix = [[]];
|
const eventsMatrix = [[]];
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event, isCheckout) {
|
emit(event, isCheckout) {
|
||||||
// isCheckout is a flag to tell you the events has been checkout
|
// isCheckout is a flag to tell you the events has been checkout
|
||||||
if (isCheckout) {
|
if (isCheckout) {
|
||||||
@@ -262,28 +320,36 @@ With the sample code above, you will finally get the last 5 to 10 minutes of eve
|
|||||||
|
|
||||||
### Replay
|
### 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
|
```html
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/style.css"
|
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
And then initialize the replayer with the following code:
|
And then initialize the replayer:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
const events = YOUR_EVENTS;
|
const events = YOUR_EVENTS;
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new Replayer(events);
|
||||||
replayer.play();
|
replayer.play();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Control the replayer by API
|
#### Control the replayer by API
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
// play
|
// play
|
||||||
replayer.play();
|
replayer.play();
|
||||||
@@ -329,29 +395,48 @@ The replayer accepts options as its constructor's second parameter, and it has t
|
|||||||
|
|
||||||
#### Use rrweb-player
|
#### 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
|
##### Installation
|
||||||
|
|
||||||
rrweb-player can also be included with `<script>`:
|
Bundler / npm (recommended):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm install rrweb-player
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import rrwebPlayer from 'rrweb-player';
|
||||||
|
import 'rrweb-player/dist/style.css';
|
||||||
|
```
|
||||||
|
|
||||||
|
Browser without bundler (ESM + import maps):
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css"
|
href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css"
|
||||||
/>
|
/>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/rrweb-player@latest/umd/rrweb-player.js"></script>
|
<script type="importmap">
|
||||||
```
|
{
|
||||||
|
"imports": {
|
||||||
Or installed by using NPM:
|
"rrweb-player": "https://cdn.jsdelivr.net/npm/rrweb-player@latest/+esm"
|
||||||
|
}
|
||||||
```shell
|
}
|
||||||
npm install --save rrweb-player
|
</script>
|
||||||
```
|
<script type="module">
|
||||||
|
|
||||||
```js
|
|
||||||
import rrwebPlayer from 'rrweb-player';
|
import rrwebPlayer from 'rrweb-player';
|
||||||
import 'rrweb-player/dist/style.css';
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Legacy direct `<script>` include (UMD fallback):
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/rrweb-player@2.0.0-alpha.20/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/rrweb-player@2.0.0-alpha.20/umd/rrweb-player.min.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Usage
|
##### Usage
|
||||||
@@ -377,15 +462,15 @@ new rrwebPlayer({
|
|||||||
| speedOption | [1, 2, 4, 8] | speed options in UI |
|
| speedOption | [1, 2, 4, 8] | speed options in UI |
|
||||||
| showController | true | whether to show the controller UI |
|
| showController | true | whether to show the controller UI |
|
||||||
| tags | {} | customize the custom events style with a key-value map |
|
| 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
|
#### 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.
|
Developers may want to extend the replayer or respond to its events, for example to notify users when inactive time starts being skipped.
|
||||||
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:
|
`Replayer` exposes a public API `on` that lets developers listen for events and customize behavior:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new Replayer(events);
|
||||||
replayer.on(EVENT_NAME, (payload) => {
|
replayer.on(EVENT_NAME, (payload) => {
|
||||||
...
|
...
|
||||||
})
|
})
|
||||||
|
|||||||
204
guide.zh_CN.md
204
guide.zh_CN.md
@@ -4,56 +4,119 @@
|
|||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
### 直接通过 `<script>` 引入
|
| 目标 | 推荐包 |
|
||||||
|
| ------------------------- | --------------------------------- |
|
||||||
|
| 大多数项目(录制 + 回放) | `@rrweb/record` + `@rrweb/replay` |
|
||||||
|
| 单包便捷接入 | `@rrweb/all` |
|
||||||
|
| 仅遗留兼容 | `rrweb` |
|
||||||
|
|
||||||
推荐通过 jsdelivr 的 CDN 安装:
|
在绝大多数生产架构中,录制端和回放端运行在不同的运行时/页面。请在被录制应用中安装 `@rrweb/record`,在回放应用中安装 `@rrweb/replay`(或 `rrweb-player`)。除非有明确的高级场景,一般不要在同一页面同时引入两者。
|
||||||
|
|
||||||
```html
|
### 1) Bundler / npm(推荐)
|
||||||
<link
|
|
||||||
rel="stylesheet"
|
```shell
|
||||||
href="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/style.css"
|
npm install @rrweb/record @rrweb/replay
|
||||||
/>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/rrweb@latest/umd/rrweb.min.js"></script>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
也可以在 URL 中指定具体的版本号,例如:
|
```js
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
```html
|
import { Replayer } from '@rrweb/replay';
|
||||||
<script src="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.21/umd/rrweb.min.js"></script>
|
import '@rrweb/replay/dist/style.css';
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 仅引入录制部分
|
如果你希望使用单一入口,也可以使用便捷包 `@rrweb/all`:
|
||||||
|
|
||||||
rrweb 代码分为录制和回放两部分,大多数时候用户在被录制的应用中只需要引入录制部分代码。同样可以通过使用 @rrweb/record 包和 CDN 服务来实现:
|
```shell
|
||||||
|
npm install @rrweb/all
|
||||||
```html
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js"></script>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
录制端的 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
|
```html
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
||||||
/>
|
/>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/umd/replay.min.js"></script>
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@rrweb/record": "https://cdn.jsdelivr.net/npm/@rrweb/record@latest/+esm",
|
||||||
|
"@rrweb/replay": "https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/+esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
|
||||||
|
record({
|
||||||
|
emit(event) {
|
||||||
|
console.log(event);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
回放端的 UMD build 会暴露全局变量 `rrwebReplay`。
|
也可以通过 `@rrweb/all` 便捷引入:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@rrweb/all@latest/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@rrweb/all": "https://cdn.jsdelivr.net/npm/@rrweb/all@latest/+esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { record, Replayer } from '@rrweb/all';
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) 传统直接 `<script>` 引入(Legacy / UMD 兼容)
|
||||||
|
|
||||||
|
仅在不支持 ESM 的兼容场景中建议使用。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.20/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.20/umd/rrweb.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
该 UMD 构建会暴露全局变量 `rrweb`。
|
||||||
|
|
||||||
|
仅录制 / 仅回放的 UMD 兼容包:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@rrweb/record@2.0.0-alpha.20/umd/record.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@rrweb/replay@2.0.0-alpha.20/umd/replay.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
对应全局变量分别是 `rrwebRecord` 和 `rrwebReplay`。
|
||||||
|
|
||||||
#### 其他包
|
#### 其他包
|
||||||
|
|
||||||
除了 `rrweb` 和 `@rrweb/record` 包之外,rrweb 还提供了其他不同用途的包。
|
除了 `@rrweb/record` 和 `@rrweb/replay` 包之外,rrweb 还提供了其他不同用途的包。
|
||||||
|
|
||||||
- [rrweb](packages/rrweb):rrweb 的核心包,包括录制和回放功能。
|
- [rrweb](packages/rrweb):rrweb 的核心包,包括录制和回放功能。
|
||||||
- [rrweb-player](packages/rrweb-player):rrweb 的图形用户界面,提供时间线和暂停、快进、加速等按钮。
|
- [rrweb-player](packages/rrweb-player):rrweb 的图形用户界面,提供时间线和暂停、快进、加速等按钮。
|
||||||
- [rrweb-snapshot](packages/rrweb-snapshot):处理快照和重建功能,将 DOM 及其状态转换为可序列化的数据结构。
|
- [rrweb-snapshot](packages/rrweb-snapshot):处理快照和重建功能,将 DOM 及其状态转换为可序列化的数据结构。
|
||||||
- [rrdom](packages/rrdom):rrweb 的虚拟 dom 包。
|
- [rrdom](packages/rrdom):rrweb 的虚拟 dom 包。
|
||||||
- [rrdom-nodejs](packages/rrdom-nodejs):用于服务器端 DOM 操作的 rrdom 的 Node.js 版本。
|
- [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/record](packages/record):一个用于录制 rrweb 会话的包。
|
||||||
- [@rrweb/replay](packages/replay):一个用于回放 rrweb 会话的包。
|
- [@rrweb/replay](packages/replay):一个用于回放 rrweb 会话的包。
|
||||||
- [@rrweb/packer](packages/packer):一个用于打包和解包 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 流式传输 `<canvas>` 的插件。
|
- [@rrweb/rrweb-plugin-canvas-webrtc-record](packages/plugins/rrweb-plugin-canvas-webrtc-record):一个用于通过 WebRTC 流式传输 `<canvas>` 的插件。
|
||||||
- [@rrweb/rrweb-plugin-canvas-webrtc-replay](packages/plugins/rrweb-plugin-canvas-webrtc-replay):一个用于通过 WebRTC 播放流式 `<canvas>` 的插件。
|
- [@rrweb/rrweb-plugin-canvas-webrtc-replay](packages/plugins/rrweb-plugin-canvas-webrtc-replay):一个用于通过 WebRTC 播放流式 `<canvas>` 的插件。
|
||||||
|
|
||||||
### 通过 npm 引入
|
|
||||||
|
|
||||||
```shell
|
|
||||||
npm install --save rrweb
|
|
||||||
```
|
|
||||||
|
|
||||||
rrweb 同时提供 commonJS 和 ES modules 两种格式的打包文件,易于和常见的打包工具配合使用。
|
|
||||||
|
|
||||||
### 兼容性
|
### 兼容性
|
||||||
|
|
||||||
由于使用 `MutationObserver` API,rrweb 不支持 IE11 以下的浏览器。可以从[这里](https://caniuse.com/#feat=mutationobserver)找到兼容的浏览器列表。
|
由于使用 `MutationObserver` API,rrweb 不支持 IE11 以下的浏览器。可以从[这里](https://caniuse.com/#feat=mutationobserver)找到兼容的浏览器列表。
|
||||||
@@ -84,10 +139,14 @@ rrweb 同时提供 commonJS 和 ES modules 两种格式的打包文件,易于
|
|||||||
|
|
||||||
### 录制
|
### 录制
|
||||||
|
|
||||||
如果通过 `<script>` 的方式仅引入录制部分,那么可以访问到全局变量 `rrwebRecord`,它和全量引入时的 `rrweb.record` 使用方式完全一致,以下示例代码将使用后者。
|
现代用法建议直接使用 `@rrweb/record` 的 `record`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
rrweb.record({
|
import { record } from '@rrweb/record';
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
// 用任意方式存储 event
|
// 用任意方式存储 event
|
||||||
},
|
},
|
||||||
@@ -99,7 +158,7 @@ rrweb 在录制时会不断将各类 event 传递给配置的 emit 方法,你
|
|||||||
调用 `record` 方法将返回一个函数,调用该函数可以终止录制:
|
调用 `record` 方法将返回一个函数,调用该函数可以终止录制:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
let stopFn = rrweb.record({
|
let stopFn = record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
if (events.length > 100) {
|
if (events.length > 100) {
|
||||||
// 当事件数量大于 100 时停止录制
|
// 当事件数量大于 100 时停止录制
|
||||||
@@ -114,7 +173,7 @@ let stopFn = rrweb.record({
|
|||||||
```js
|
```js
|
||||||
let events = [];
|
let events = [];
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event) {
|
emit(event) {
|
||||||
// 将 event 存入 events 数组中
|
// 将 event 存入 events 数组中
|
||||||
events.push(event);
|
events.push(event);
|
||||||
@@ -140,7 +199,7 @@ setInterval(save, 10 * 1000);
|
|||||||
|
|
||||||
#### 配置参数
|
#### 配置参数
|
||||||
|
|
||||||
`rrweb.record(config)` 的 config 部分接受以下参数
|
`record(config)` 的 config 部分接受以下参数
|
||||||
|
|
||||||
| key | 默认值 | 功能 |
|
| key | 默认值 | 功能 |
|
||||||
| ------------------------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
@@ -192,7 +251,7 @@ setInterval(save, 10 * 1000);
|
|||||||
// 使用二维数组来存放多个 event 数组
|
// 使用二维数组来存放多个 event 数组
|
||||||
const eventsMatrix = [[]];
|
const eventsMatrix = [[]];
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event, isCheckout) {
|
emit(event, isCheckout) {
|
||||||
// isCheckout 是一个标识,告诉你重新制作了快照
|
// isCheckout 是一个标识,告诉你重新制作了快照
|
||||||
if (isCheckout) {
|
if (isCheckout) {
|
||||||
@@ -227,7 +286,7 @@ window.onerror = function () {
|
|||||||
// 使用二维数组来存放多个 event 数组
|
// 使用二维数组来存放多个 event 数组
|
||||||
const eventsMatrix = [[]];
|
const eventsMatrix = [[]];
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit(event, isCheckout) {
|
emit(event, isCheckout) {
|
||||||
// isCheckout 是一个标识,告诉你重新制作了快照
|
// isCheckout 是一个标识,告诉你重新制作了快照
|
||||||
if (isCheckout) {
|
if (isCheckout) {
|
||||||
@@ -258,28 +317,36 @@ window.onerror = function () {
|
|||||||
|
|
||||||
### 回放
|
### 回放
|
||||||
|
|
||||||
回放时需要引入对应的 CSS 文件:
|
在 bundler 场景下,可在入口文件中引入 CSS:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import '@rrweb/replay/dist/style.css';
|
||||||
|
```
|
||||||
|
|
||||||
|
在浏览器 no-build 场景下,也可以在 HTML 中引入 CSS:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/style.css"
|
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
再通过以下 JS 代码初始化 replayer:
|
然后通过以下 JS 代码初始化 replayer:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
|
||||||
const events = YOUR_EVENTS;
|
const events = YOUR_EVENTS;
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new Replayer(events);
|
||||||
replayer.play();
|
replayer.play();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 使用 API 控制回放
|
#### 使用 API 控制回放
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new Replayer(events);
|
||||||
|
|
||||||
// 播放
|
// 播放
|
||||||
replayer.play();
|
replayer.play();
|
||||||
@@ -299,7 +366,7 @@ replayer.destroy();
|
|||||||
|
|
||||||
#### 配置参数
|
#### 配置参数
|
||||||
|
|
||||||
可以通过 `new rrweb.Replayer(events, options)` 的方式向 rrweb 传递回放时的配置参数,具体配置如下:
|
可以通过 `new Replayer(events, options)` 的方式向 rrweb 传递回放时的配置参数,具体配置如下:
|
||||||
|
|
||||||
| key | 默认值 | 功能 |
|
| key | 默认值 | 功能 |
|
||||||
| ------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
@@ -327,25 +394,44 @@ rrweb 自带的回放只提供所有的 JS API 以及最基本的 UI,如果需
|
|||||||
|
|
||||||
##### 安装
|
##### 安装
|
||||||
|
|
||||||
rrweb-player 同样可以使用 CDN 方式安装:
|
Bundler / npm(推荐):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm install rrweb-player
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import rrwebPlayer from 'rrweb-player';
|
||||||
|
import 'rrweb-player/dist/style.css';
|
||||||
|
```
|
||||||
|
|
||||||
|
无 bundler 的浏览器场景(ESM + import maps):
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css"
|
href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css"
|
||||||
/>
|
/>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/rrweb-player@latest/umd/rrweb-player.js"></script>
|
<script type="importmap">
|
||||||
```
|
{
|
||||||
|
"imports": {
|
||||||
或者通过 npm 安装:
|
"rrweb-player": "https://cdn.jsdelivr.net/npm/rrweb-player@latest/+esm"
|
||||||
|
}
|
||||||
```shell
|
}
|
||||||
npm install --save rrweb-player
|
</script>
|
||||||
```
|
<script type="module">
|
||||||
|
|
||||||
```js
|
|
||||||
import rrwebPlayer from 'rrweb-player';
|
import rrwebPlayer from 'rrweb-player';
|
||||||
import 'rrweb-player/dist/style.css';
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Legacy 直接 `<script>` 引入(UMD 兼容):
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/rrweb-player@2.0.0-alpha.20/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/rrweb-player@2.0.0-alpha.20/umd/rrweb-player.min.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
##### 使用
|
##### 使用
|
||||||
@@ -373,16 +459,16 @@ new rrwebPlayer({
|
|||||||
| speedOption | [1, 2, 4, 8] | 倍速播放可选值 |
|
| speedOption | [1, 2, 4, 8] | 倍速播放可选值 |
|
||||||
| showController | true | 是否显示播放器控制 UI |
|
| showController | true | 是否显示播放器控制 UI |
|
||||||
| tags | {} | 可以以 key value 的形式展示自定义事件在时间轴上的颜色 |
|
| tags | {} | 可以以 key value 的形式展示自定义事件在时间轴上的颜色 |
|
||||||
| ... | - | 其它所有 rrweb Replayer 的配置参数均可透传 |
|
| ... | - | 其它所有 Replayer 的配置参数均可透传 |
|
||||||
|
|
||||||
#### 事件
|
#### 事件
|
||||||
|
|
||||||
开发者可能希望监听回放时的各类事件,例如在跳过无用户操作的时间时给用户一些提示。
|
开发者可能希望监听回放时的各类事件,例如在跳过无用户操作的时间时给用户一些提示。
|
||||||
|
|
||||||
rrweb 的 Replayer 提供了 `on` API 用于提供该功能
|
Replayer 提供了 `on` API 用于实现该功能
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const replayer = new rrweb.Replayer(events);
|
const replayer = new Replayer(events);
|
||||||
replayer.on(EVENT_NAME, (payload) => {
|
replayer.on(EVENT_NAME, (payload) => {
|
||||||
...
|
...
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
# @rrweb/all
|
# @rrweb/all
|
||||||
|
|
||||||
Convenience package that includes a bundle of rrweb packages.
|
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:
|
Includes the following packages:
|
||||||
|
|
||||||
@@ -11,19 +20,47 @@ Includes the following packages:
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
### 1) Bundler / npm
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @rrweb/all
|
npm install @rrweb/all
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { record, replay, pack, unpack } from '@rrweb/all';
|
import { record, Replayer, pack, unpack } from '@rrweb/all';
|
||||||
|
import '@rrweb/all/dist/style.css';
|
||||||
// use record, replay, pack, unpack as you would with the individual packages.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@rrweb/all@latest/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@rrweb/all": "https://cdn.jsdelivr.net/npm/@rrweb/all@latest/+esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { record, Replayer, pack, unpack } from '@rrweb/all';
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Legacy Direct `<script>` Include (UMD fallback)
|
||||||
|
|
||||||
|
Use this only for compatibility with non-module environments.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@rrweb/all@latest/umd/all.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
## Sponsors
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ https://user-images.githubusercontent.com/4106/186701616-fd71a107-5d53-423c-ba09
|
|||||||
```js
|
```js
|
||||||
// Record side
|
// Record side
|
||||||
|
|
||||||
import rrweb from 'rrweb';
|
import { record } from '@rrweb/record';
|
||||||
import { RRWebPluginCanvasWebRTCRecord } from 'rrweb-plugin-canvas-webrtc-record';
|
import { RRWebPluginCanvasWebRTCRecord } from '@rrweb/rrweb-plugin-canvas-webrtc-record';
|
||||||
|
|
||||||
const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({
|
const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({
|
||||||
signalSendCallback: (msg) => {
|
signalSendCallback: (msg) => {
|
||||||
@@ -24,7 +24,7 @@ const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit: (event) => {
|
emit: (event) => {
|
||||||
// send these events to the `replayer.addEvent(event)`, how you do that is up to you
|
// 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
|
// you can send them to a server for example which can then send them to the replayer
|
||||||
@@ -42,8 +42,8 @@ rrweb.record({
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// Replay side
|
// Replay side
|
||||||
import rrweb from 'rrweb';
|
import { Replayer } from '@rrweb/replay';
|
||||||
import { RRWebPluginCanvasWebRTCReplay } from 'rrweb-plugin-canvas-webrtc-replay';
|
import { RRWebPluginCanvasWebRTCReplay } from '@rrweb/rrweb-plugin-canvas-webrtc-replay';
|
||||||
|
|
||||||
const webRTCReplayPlugin = new RRWebPluginCanvasWebRTCReplay({
|
const webRTCReplayPlugin = new RRWebPluginCanvasWebRTCReplay({
|
||||||
canvasFoundCallback(canvas, context) {
|
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!
|
UNSAFE_replayCanvas: true, // turn canvas replay on!
|
||||||
liveMode: true, // live mode is needed to stream events to the replayer
|
liveMode: true, // live mode is needed to stream events to the replayer
|
||||||
plugins: [webRTCReplayPlugin.initPlugin()],
|
plugins: [webRTCReplayPlugin.initPlugin()],
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ https://user-images.githubusercontent.com/4106/186701616-fd71a107-5d53-423c-ba09
|
|||||||
```js
|
```js
|
||||||
// Record side
|
// Record side
|
||||||
|
|
||||||
import rrweb from 'rrweb';
|
import { record } from '@rrweb/record';
|
||||||
import { RRWebPluginCanvasWebRTCRecord } from '@rrweb/rrweb-plugin-canvas-webrtc-record';
|
import { RRWebPluginCanvasWebRTCRecord } from '@rrweb/rrweb-plugin-canvas-webrtc-record';
|
||||||
|
|
||||||
const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({
|
const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({
|
||||||
@@ -24,7 +24,7 @@ const webRTCRecordPlugin = new RRWebPluginCanvasWebRTCRecord({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit: (event) => {
|
emit: (event) => {
|
||||||
// send these events to the `replayer.addEvent(event)`, how you do that is up to you
|
// 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
|
// you can send them to a server for example which can then send them to the replayer
|
||||||
@@ -42,7 +42,7 @@ rrweb.record({
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// Replay side
|
// Replay side
|
||||||
import rrweb from 'rrweb';
|
import { Replayer } from '@rrweb/replay';
|
||||||
import { RRWebPluginCanvasWebRTCReplay } from '@rrweb/rrweb-plugin-canvas-webrtc-replay';
|
import { RRWebPluginCanvasWebRTCReplay } from '@rrweb/rrweb-plugin-canvas-webrtc-replay';
|
||||||
|
|
||||||
const webRTCReplayPlugin = new RRWebPluginCanvasWebRTCReplay({
|
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!
|
UNSAFE_replayCanvas: true, // turn canvas replay on!
|
||||||
liveMode: true, // live mode is needed to stream events to the replayer
|
liveMode: true, // live mode is needed to stream events to the replayer
|
||||||
plugins: [webRTCReplayPlugin.initPlugin()],
|
plugins: [webRTCReplayPlugin.initPlugin()],
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ npm install @rrweb/rrweb-plugin-sequential-id-record
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import rrweb from 'rrweb';
|
import { record } from '@rrweb/record';
|
||||||
import { getRecordSequentialIdPlugin } from '@rrweb/rrweb-plugin-sequential-id-record';
|
import { getRecordSequentialIdPlugin } from '@rrweb/rrweb-plugin-sequential-id-record';
|
||||||
|
|
||||||
rrweb.record({
|
record({
|
||||||
emit: function emit(event) {
|
emit: function emit(event) {
|
||||||
// send events to server
|
// send events to server
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ npm install @rrweb/rrweb-plugin-sequential-id-replay
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import rrweb from 'rrweb';
|
import { Replayer } from '@rrweb/replay';
|
||||||
import { getReplaySequentialIdPlugin } from '@rrweb/rrweb-plugin-sequential-id-replay';
|
import { getReplaySequentialIdPlugin } from '@rrweb/rrweb-plugin-sequential-id-replay';
|
||||||
|
|
||||||
const replayer = new rrweb.Replayer(events, {
|
const replayer = new Replayer(events, {
|
||||||
plugins: [
|
plugins: [
|
||||||
getReplaySequentialIdPlugin({
|
getReplaySequentialIdPlugin({
|
||||||
// make sure this is the same as the record side
|
// make sure this is the same as the record side
|
||||||
|
|||||||
@@ -5,10 +5,41 @@ See the [guide](../../guide.md) for more info on rrweb.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
### 1) Bundler / npm (Recommended)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @rrweb/record
|
npm install @rrweb/record
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) Browser Without Bundler (ESM + import maps)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@rrweb/record": "https://cdn.jsdelivr.net/npm/@rrweb/record@latest/+esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Legacy Direct `<script>` Include (UMD fallback)
|
||||||
|
|
||||||
|
Use this only for compatibility with non-module environments.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
The legacy UMD global is `rrwebRecord`.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|||||||
@@ -5,14 +5,55 @@ See the [guide](../../guide.md) for more info on rrweb.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
### 1) Bundler / npm (Recommended)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @rrweb/replay
|
npm install @rrweb/replay
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
import '@rrweb/replay/dist/style.css';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) Browser Without Bundler (ESM + import maps)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@rrweb/replay": "https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/+esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Legacy Direct `<script>` Include (UMD fallback)
|
||||||
|
|
||||||
|
Use this only for compatibility with non-module environments.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/umd/replay.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
The legacy UMD global is `rrwebReplay`.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { Replayer } from '@rrweb/replay';
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
import '@rrweb/replay/dist/style.css';
|
||||||
|
|
||||||
const replayer = new Replayer(events, {
|
const replayer = new Replayer(events, {
|
||||||
// options
|
// options
|
||||||
|
|||||||
@@ -12,25 +12,46 @@ rrweb-player uses rrweb's Replayer under the hood, but as Replayer doesn't inclu
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
rrweb-player can also be included with `<script>`:
|
### 1) Bundler / npm (Recommended)
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm install rrweb-player
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import rrwebPlayer from 'rrweb-player';
|
||||||
|
import 'rrweb-player/dist/style.css';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) Browser Without Bundler (ESM + import maps)
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css"
|
href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css"
|
||||||
/>
|
/>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/rrweb-player@latest/umd/rrweb-player.js"></script>
|
<script type="importmap">
|
||||||
```
|
{
|
||||||
|
"imports": {
|
||||||
Or installed by using NPM:
|
"rrweb-player": "https://cdn.jsdelivr.net/npm/rrweb-player@latest/+esm"
|
||||||
|
}
|
||||||
```shell
|
}
|
||||||
npm install --save rrweb-player
|
</script>
|
||||||
```
|
<script type="module">
|
||||||
|
|
||||||
```js
|
|
||||||
import rrwebPlayer from 'rrweb-player';
|
import rrwebPlayer from 'rrweb-player';
|
||||||
import 'rrweb-player/dist/style.css';
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Legacy Direct `<script>` Include (UMD fallback)
|
||||||
|
|
||||||
|
Use this only for compatibility with non-module environments.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/rrweb-player@latest/umd/rrweb-player.min.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -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)
|
[**🍳 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
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@rrweb/record": "https://cdn.jsdelivr.net/npm/@rrweb/record@latest/+esm",
|
||||||
|
"@rrweb/replay": "https://cdn.jsdelivr.net/npm/@rrweb/replay@latest/+esm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import { record } from '@rrweb/record';
|
||||||
|
import { Replayer } from '@rrweb/replay';
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3) Legacy Direct `<script>` Include (UMD fallback)
|
||||||
|
|
||||||
|
Use this only for compatibility with non-module environments; modern browsers support the importmap method [since 2023](https://caniuse.com/?search=import+map)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/style.css"
|
||||||
|
/>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/rrweb@latest/umd/rrweb.min.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
**[rrweb](https://github.com/rrweb-io/rrweb)** mainly includes two funtions:
|
**[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
|
- **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
|
## Roadmap
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user