Controlling when recording starts and stops

If you already server-side render your initial HTML, and have sufficient information when rendering the initial HTML to determine whether the Meticulous recorder should record the session, then you can conditionally pre-render the Meticulous recorder script tag into your initial HTML. In this case you can stop reading here.

If however you need to make frontend web requests to determine whether to start recording (for example fetching user data from an API), then you can use network-recorder.bundle.js.

Meticulous needs to be able to record all network requests & responses from the very start of your page load for a session to replay correctly. That means that if you only want to record sessions for certain users with certain attributes then you have an issue: you need to wait for the user information to load before you know whether you can enable the recorder, but if you enable the recorder after the user information has loaded then the recorder won't be able to capture the initial request & response to load the user information, or other early network responses.

network-recorder.bundle.js solves this: you include it in the HTML originally returned from the server for all sessions, and it'll temporarily record any network requests in memory (but not send it to the server).

If when you load the user data you find out you don't want to record the session then you can call the stopIntercepting() method from @alwaysmeticulous/recorder-loader, and any recorded data will be discarded.

If when you load the user data you find out you do want to record the session then you can call the tryLoadAndStartRecorder() from @alwaysmeticulous/recorder-loader, at which point the data will start getting sent to the Meticulous servers. You can then stop recording a session at any point by calling the stopRecording() method returned by tryLoadAndStartRecorder().

Setting up conditional recording using network-recorder.bundle.js

Step 1: Add the network-recorder.bundle.js script tag

Important: The Meticulous Recorder script should be the first script to load, and have no async or defer attributes

Libraries you depend on may snapshot references to window.fetch or window.XMLHttpRequest early in the page lifecycle, which means if Meticulous is not the first script to load it may not be able to record all the network responses required for your app to function (learn more). Therefore the recorder script must be the first script to load in order to be guaranteed to capture all network requests correctly. This means:

  1. It should be added to your index.html file, before any other script tags.
  2. It should not have any async or defer attributes set. If using NextJS then it should use the native script tag instead of the NextJS Script component.
  3. It should be present in the initial HTML returned from the server -- you can not add the script tag dynamically using javascript, since if you do so the browser may execute the script after other scripts have loaded. If you need to include the script tag in your HTML only in certain environments then this must be done either server-side, or at build time by templating your HTML.

If it's not possible to meet these requirements then you can use an NPM dependency instead of a script tag.

Add the network-recorder.bundle.js script tag to your index.html, or the HTML returned from your server:

<head>
  ...
  <script
    src="https://snippet.meticulous.ai/record/v1/network-recorder.bundle.js">
  </script>

  <!-- network-recorder.bundle.js should be added before your app -->
  ...
  <script src="main_app.js"></script>
</head>

Step 2: Conditionally start recording

Load the data you need to determine whether to start recording. If you wish to record the session and start sending data to Meticulous then call tryLoadAndStartRecorder(), otherwise call stopIntercepting():

import { tryLoadAndStartRecorder, stopIntercepting } from "@alwaysmeticulous/recorder-loader";

...

const user = await loadUser();
if (isNotProduction() && shouldRecord(user))
  // Note: all errors are caught and logged, so no need to surround with try/catch
  await tryLoadAndStartRecorder({
    recordingToken: '<RECORDING_TOKEN>',
    isProduction: false,
  });
} else {
  await stopIntercepting();
}

Alternative: using a NPM dependency

If you prefer to use a NPM dependency, rather than a script tag, you can instead use the tryInstallMeticulousIntercepts() function function, instead of network-recorder.bundle.js. However this is not recommended since it's easy to miss network requests if libraries you use snapshot references to window.fetch or window.XMLHttpRequest early in the page lifecycle (learn more).

If when you load the user data you find out you don't want to record the session then you can call the stopRecording() method returned by tryInstallMeticulousIntercepts(), and any recorded data will be discarded. If when you load the user data you find out you do want to record the session then you can call the startRecordingSession() method returned by tryInstallMeticulousIntercepts(), at which point the data will start getting sent to the Meticulous servers. You can then stop recording a session at any point by calling the stopRecording() method returned by startRecordingSession().

Note: tryInstallMeticulousIntercepts will return a successful promise even if for some reason the browser is unable to load the required scripts, so it's safe, and indeed required, to block your app loading on the promise returned by tryInstallMeticulousIntercepts resolving.