Skip to content

Network Recorder and Replayer ​

This feature aims to provide developers with more information about the bug scene. There are some options for recording and replaying network output.

Enable Recording Network ​

You can enable using default option like this:

js
import { record } from '@rrweb/record';
import { getRecordNetworkPlugin } from '@rrweb/rrweb-plugin-network-record';

record({
  emit: function emit(event) {
    events.push(event);
  },
  // to use default record option
  plugins: [getRecordNetworkPlugin()],
});

You can also customize the behavior of logger like this:

js
import { record } from '@rrweb/record';
import { getRecordNetworkPlugin } from '@rrweb/rrweb-plugin-network-record';

const recordingId = crypto.randomUUID();

record({
  emit: function emit(event) {
    fetch(`https://api.rrweb.com/recordings/${recordingId}/events`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        events: [event],
      }),
    });
  },
  // customized record options
  plugins: [
    getRecordNetworkPlugin({
      initiatorTypes: ['fetch', 'xmlhttprequest'],
      // mask/block recording event for request
      transformRequestFn: (request) => {
        // request.name is url
        if (request.name.includes('api.rrweb.com')) return; // skip request
        delete request.requestHeaders?.Authorization; // remove sensitive data
        request.responseBody = maskTextFn(request.responseBody);
        return request;
      },
      recordHeaders: true,
      recordBody: true,
      recordInitialRequests: false,
    }),
  ],
});

alert: If you are uploading events to a server, you should always use transformRequestFn to mask/block recording events for these requests or else you will cause a nasty loop.

All options are described below:

keydefaultdescription
initiatorTypes['fetch','xmlhttprequest','img',...]Default value contains names of all initiator types. You can override it by setting the types you need.
transformRequestFn(request) => requestTransform recording event for request to block (skip) or mask/transform request (e.g. to hide sensitive data)
recordHeadersfalseRecord the request & response headers for fetch and xmlhttprequest requests
recordBodyfalseRecord the request & response bodies for fetch and xmlhttprequest requests
recordInitialRequestsfalseRecord an event for all requests prior to record() being called

Replay Network Requests ​

It is up to you to decide how to best replay your network events using the onNetworkData callback.

js
import rrweb from 'rrweb';
import { getReplayNetworkPlugin } from '@rrweb/rrweb-plugin-network-replay';

const replayer = new rrweb.Replayer(events, {
  plugins: [
    getReplayNetworkPlugin({
      onNetworkData: ({ requests }) => {
        for (const request of requests) {
          const name = request.name; // url
          const method = request.method;
          const status = request.status;
          console.log(`${method} ${name} ${status}`);
        }
      },
    }),
  ],
});
replayer.play();

Description of replay option is as follows:

keydefaultdescription
onNetworkDataundefinedYou could use this interface to replay the network requests in a simulated browser console

Technical Implementation ​

This implementation records fetch and XMLHttpRequest by patching their object & methods. We record document navigation using PerformanceNavigationTiming and we use PerformanceResourceTiming for recording everything else (script, img, link etc.) via PerformanceObserver API.

For more information please see [network-plugin] Feat: Capture network events #1105 PR.