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:
Justin Halsall
2026-02-17 13:59:02 +01:00
committed by GitHub
parent dab8c29da8
commit bcf93ca926
37 changed files with 667 additions and 217 deletions

View 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.

View File

@@ -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 的开发。

View File

@@ -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();

View File

@@ -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();

View File

@@ -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'],

View File

@@ -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'],

View File

@@ -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,
});

View File

@@ -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,
});

View File

@@ -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);

View File

@@ -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);

View File

@@ -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/).

View File

@@ -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/) 的方式进行开发。

View File

@@ -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)

View File

@@ -42,7 +42,7 @@
### 自定义回放 UI
rrweb Replayer 和 rrweb-player 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。
`Replayer` 和 rrweb-player 的 UI 不能满足需求时,可以通过自定义回放 UI 制作属于你自己的回放器。
[链接](./customize-replayer.zh_CN.md)

View File

@@ -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();

View File

@@ -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();

View File

@@ -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);

View File

@@ -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,
});

View File

@@ -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,
});
```

View File

@@ -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,
});
```

View File

@@ -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);

View File

@@ -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);

View File

@@ -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],
});
```

View File

@@ -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],
});
```

View File

@@ -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();
```

View File

@@ -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();
```

203
guide.md
View File

@@ -6,57 +6,119 @@
## 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
<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>
### 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
<script src="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.21/umd/rrweb.min.js"></script>
```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
<script src="https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js"></script>
```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
<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>
<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
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 `<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
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
<link
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
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 `<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
<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.js"></script>
<script type="importmap">
{
"imports": {
"rrweb-player": "https://cdn.jsdelivr.net/npm/rrweb-player@latest/+esm"
}
}
</script>
<script type="module">
import rrwebPlayer from 'rrweb-player';
</script>
```
Or installed by using NPM
Legacy direct `<script>` include (UMD fallback):
```shell
npm install --save rrweb-player
```
```js
import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
```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
@@ -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) => {
...
})

View File

@@ -4,56 +4,119 @@
## 安装
### 直接通过 `<script>` 引入
| 目标 | 推荐包 |
| ------------------------- | --------------------------------- |
| 大多数项目(录制 + 回放) | `@rrweb/record` + `@rrweb/replay` |
| 单包便捷接入 | `@rrweb/all` |
| 仅遗留兼容 | `rrweb` |
推荐通过 jsdelivr 的 CDN 安装:
在绝大多数生产架构中,录制端和回放端运行在不同的运行时/页面。请在被录制应用中安装 `@rrweb/record`,在回放应用中安装 `@rrweb/replay`(或 `rrweb-player`)。除非有明确的高级场景,一般不要在同一页面同时引入两者。
```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>
### 1) Bundler / npm推荐
```shell
npm install @rrweb/record @rrweb/replay
```
也可以在 URL 中指定具体的版本号,例如:
```html
<script src="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.21/umd/rrweb.min.js"></script>
```js
import { record } from '@rrweb/record';
import { Replayer } from '@rrweb/replay';
import '@rrweb/replay/dist/style.css';
```
#### 仅引入录制部分
如果你希望使用单一入口,也可以使用便捷包 `@rrweb/all`
rrweb 代码分为录制和回放两部分,大多数时候用户在被录制的应用中只需要引入录制部分代码。同样可以通过使用 @rrweb/record 包和 CDN 服务来实现:
```html
<script src="https://cdn.jsdelivr.net/npm/@rrweb/record@latest/umd/record.min.js"></script>
```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
<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>
<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-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 流式传输 `<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` APIrrweb 不支持 IE11 以下的浏览器。可以从[这里](https://caniuse.com/#feat=mutationobserver)找到兼容的浏览器列表。
@@ -84,10 +139,14 @@ rrweb 同时提供 commonJS 和 ES modules 两种格式的打包文件,易于
### 录制
如果通过 `<script>` 的方式仅引入录制部分,那么可以访问到全局变量 `rrwebRecord`,它和全量引入时的 `rrweb.record` 使用方式完全一致,以下示例代码将使用后者。
现代用法建议直接使用 `@rrweb/record``record`
```js
rrweb.record({
import { record } from '@rrweb/record';
```
```js
record({
emit(event) {
// 用任意方式存储 event
},
@@ -99,7 +158,7 @@ rrweb 在录制时会不断将各类 event 传递给配置的 emit 方法,你
调用 `record` 方法将返回一个函数,调用该函数可以终止录制:
```js
let stopFn = rrweb.record({
let stopFn = record({
emit(event) {
if (events.length > 100) {
// 当事件数量大于 100 时停止录制
@@ -114,7 +173,7 @@ let stopFn = rrweb.record({
```js
let events = [];
rrweb.record({
record({
emit(event) {
// 将 event 存入 events 数组中
events.push(event);
@@ -140,7 +199,7 @@ setInterval(save, 10 * 1000);
#### 配置参数
`rrweb.record(config)` 的 config 部分接受以下参数
`record(config)` 的 config 部分接受以下参数
| key | 默认值 | 功能 |
| ------------------------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -192,7 +251,7 @@ setInterval(save, 10 * 1000);
// 使用二维数组来存放多个 event 数组
const eventsMatrix = [[]];
rrweb.record({
record({
emit(event, isCheckout) {
// isCheckout 是一个标识,告诉你重新制作了快照
if (isCheckout) {
@@ -227,7 +286,7 @@ window.onerror = function () {
// 使用二维数组来存放多个 event 数组
const eventsMatrix = [[]];
rrweb.record({
record({
emit(event, isCheckout) {
// 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
<link
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
import { Replayer } from '@rrweb/replay';
const events = YOUR_EVENTS;
const replayer = new rrweb.Replayer(events);
const replayer = new Replayer(events);
replayer.play();
```
#### 使用 API 控制回放
```js
const replayer = new rrweb.Replayer(events);
const replayer = new Replayer(events);
// 播放
replayer.play();
@@ -299,7 +366,7 @@ replayer.destroy();
#### 配置参数
可以通过 `new rrweb.Replayer(events, options)` 的方式向 rrweb 传递回放时的配置参数,具体配置如下:
可以通过 `new Replayer(events, options)` 的方式向 rrweb 传递回放时的配置参数,具体配置如下:
| 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
<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.js"></script>
<script type="importmap">
{
"imports": {
"rrweb-player": "https://cdn.jsdelivr.net/npm/rrweb-player@latest/+esm"
}
}
</script>
<script type="module">
import rrwebPlayer from 'rrweb-player';
</script>
```
或者通过 npm 安装
Legacy 直接 `<script>` 引入UMD 兼容)
```shell
npm install --save rrweb-player
```
```js
import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
```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] | 倍速播放可选值 |
| 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) => {
...
})

View File

@@ -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
<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

View File

@@ -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()],

View File

@@ -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()],

View File

@@ -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
},

View File

@@ -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

View File

@@ -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
<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
```js

View File

@@ -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
<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
```js
import { Replayer } from '@rrweb/replay';
import '@rrweb/replay/dist/style.css';
const replayer = new Replayer(events, {
// options

View File

@@ -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 `<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
<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.js"></script>
<script type="importmap">
{
"imports": {
"rrweb-player": "https://cdn.jsdelivr.net/npm/rrweb-player@latest/+esm"
}
}
</script>
<script type="module">
import rrwebPlayer from 'rrweb-player';
</script>
```
Or installed by using NPM
### 3) Legacy Direct `<script>` Include (UMD fallback)
```shell
npm install --save rrweb-player
```
Use this only for compatibility with non-module environments.
```js
import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
```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

View File

@@ -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
<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
**[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