Skip to content
Docs menu · Electron

Install — Desktop

Install AnyReplay in an Electron App

Record Electron app windows with @anyreplay/electron: set it up in the main process, the preload script and the renderer, then allow ingest in your CSP.

Each window of an Electron app is a web page, so the Electron SDK records it with the browser SDK — the same masking, the same delivery, the same player. What it adds is what a web page cannot know: which app it is, the app's version, and when the app is about to quit.

Install

npm install @anyreplay/electron

Set it up

One call in each of Electron's three contexts.

import { setupAnyReplay } from '@anyreplay/electron/main';

setupAnyReplay({
  // Your app id — electron-builder's appId. Required once the project lists allowed domains or apps.
  // appId: 'com.example.app'
});
main.ts — the main process

setupAnyReplay tells the windows the app id and app.getVersion(), holds quitting back for up to 1.5 seconds while every window sends what it recorded, and records an uncaught exception in the main process into the focused window's session as an error, as if the window had caught it: it appears with the page's own errors and marks the session as having one. It only observes those exceptions, so your app handles them exactly as before.

import { exposeAnyReplay } from '@anyreplay/electron/preload';

exposeAnyReplay();
preload.ts

exposeAnyReplay gives the page window.anyreplayElectron through contextBridge: the app info, a flush the main process can ask for, and main-process errors — no general access to IPC. It works with contextIsolation, sandbox and no nodeIntegration, which are Electron's defaults. A sandboxed preload cannot load packages at run time, so bundle it, as Electron Forge and electron-vite do.

import { init } from '@anyreplay/electron';

init({
  projectKey: 'YOUR_PROJECT_KEY',
  ingestUrl: 'https://in.anyreplay.com',
  // Stop recording after this many sessions in a calendar month.
  // maxSessionsPerMonth: 10000,
  // Form fields are masked: what visitors type replays as asterisks.
  // Passwords, one-time codes and card fields are masked either way.
  // Uncomment the first line to record what visitors type, or the
  // second to hide rich-text editors too.
  // maskAllInputs: false,
  // maskAllTyping: true
});
The renderer, in every window

init takes every option of the browser SDK. It returns at once and starts recording when the app info arrives a moment later; calls made before then are queued. It also flushes whenever the window loses focus — turn that off with flushOnBlur: false.

The app id

A packaged window loads from file:// and has no web origin, so a project that lists allowed domains or apps admits it by its app id. Electron has no API for the bundle id, so pass it to setupAnyReplay — the appId of electron-builder or the appBundleId of Forge — and list the same id under the project's Allowed apps. Without it the id is made from the app's name (Acme Notes becomes acme-notes).

Windows and sessions

Each window is its own session, because the session id lives in the window's sessionStorage. The visitor id lives in localStorage, which Electron keeps between launches and shares between windows, so one person is one visitor however many windows they open.

Content Security Policy

If your windows set a Content Security Policy, add the ingest host to connect-src, or recordings are blocked before they leave the window. See Content Security Policy.

connect-src 'self' https://in.anyreplay.com

Requirements

  • Electron 28 or later. Tested with Electron 38 on macOS.
  • Styles, fonts and images are recorded into the session itself, because a file:// address means nothing to the player later.