Electron

Set up Human Behavior in an Electron desktop app.

Quickstart

Human Behavior runs inside Electron's renderer process — the same window that loads your HTML and JS. rrweb (the session recorder) needs a DOM, so the SDK cannot be initialized from the main process.

Renderer only. Don't require('humanbehavior-js') from main.js. Load it from your HTML (CDN or bundled) or from a renderer-side script file.

Step 1: Installation

Either install as a dependency and bundle it with your renderer, or drop the CDN bundle into your HTML.

npm install humanbehavior-js
<script src="https://unpkg.com/humanbehavior-js@latest"></script>

Step 2: Allow the ingestion endpoint in your CSP

Electron applies the Content-Security-Policy on every renderer. Human Behavior sends HTTP POSTs to https://ingest.humanbehavior.co (or your reverse proxy), so that origin must appear in connect-src. Without this, every request fails silently with Refused to connect.

main.js
const { app, BrowserWindow, session } = require('electron');

app.whenReady().then(() => {
  session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
    callback({
      responseHeaders: {
        ...details.responseHeaders,
        'Content-Security-Policy': [
          "default-src 'self'; " +
          "script-src 'self' 'unsafe-inline' https://unpkg.com; " +
          "connect-src 'self' https://ingest.humanbehavior.co; " +
          "img-src 'self' data: blob:; " +
          "style-src 'self' 'unsafe-inline';"
        ],
      },
    });
  });

  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: { contextIsolation: true },
  });
  win.loadFile('renderer/index.html');
});

If you're using a reverse proxy on your own domain, replace https://ingest.humanbehavior.co with that domain. If you run Human Behavior locally for development, add http://localhost:8000 (or your port) to connect-src.

Step 3: Initialize the tracker in the renderer

Bundled (npm)

renderer/renderer.js
import { HumanBehaviorTracker } from 'humanbehavior-js';

const tracker = HumanBehaviorTracker.init('your-api-key');

CDN bundle

The UMD bundle exposes both window.HumanBehaviorTracker and a window.humanbehavior.init(apiKey, options) helper. The init signature is init(apiKey, options?) — any custom ingestionUrl goes inside options:

renderer/index.html
<script src="https://unpkg.com/humanbehavior-js@latest"></script>
<script>
  const tracker = window.humanbehavior.init('your-api-key', {
    ingestionUrl: 'https://ingest.humanbehavior.co',
  });
</script>

Known gotcha: passing logLevel: 'debug' in the options object currently throws TypeError: this.configureLogging is not a function inside the UMD bundle. If you need verbose logs, call window.HumanBehaviorTracker.configureLogging({ level: 'debug' }) before init() instead.

Step 4: Custom events and identify

Once initialized, use the instance returned by init():

tracker.customEvent('feature_opened', { feature: 'export' });

tracker.identifyUser({
  userId: user.id,
  userProperties: {
    email: user.email,
    name: user.name,
  },
});

That's it! Clicks, page views, console errors, and rage clicks are captured automatically across all renderer windows that initialize the SDK.

Multiple windows

Each BrowserWindow is a separate JS context, so each window that loads your renderer code gets its own tracker instance — same endUserId cookie when they share a session, distinct sessionIds per window. If a window doesn't load the SDK, its interactions simply aren't tracked.

Automating tests against your renderer

If you drive your Electron app from Playwright, Puppeteer, or Claude's browser tools, launch Electron with remote debugging enabled so the test harness can attach to the renderer:

electron . --remote-debugging-port=9222 --remote-allow-origins=*

Then connect to http://localhost:9222 over the Chrome DevTools Protocol.

Troubleshooting

  • Requests show as blocked in DevTools → Network. Your CSP is missing connect-src for the ingestion host. Add https://ingest.humanbehavior.co (or your proxy domain).
  • TypeError: this.configureLogging is not a function. You passed logLevel in the UMD init. Call HumanBehaviorTracker.configureLogging({ level: 'debug' }) before init() instead.
  • Nothing shows up in the dashboard. Confirm you're calling init from the renderer, not the main process. typeof window === 'undefined' in the code path means you're in main.
  • window.humanbehavior is undefined. The CDN script tag didn't load — check for a Refused to load CSP error for script-src and add https://unpkg.com (or whatever host you pulled the bundle from).