JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 283
  • Score
    100M100P100Q64314F
  • License MIT

Session recording for web and mini programs. Record user behavior, replay it, debug faster.

Package Exports

  • sigillum-js
  • sigillum-js/miniapp
  • sigillum-js/miniapp/taro
  • sigillum-js/react
  • sigillum-js/replay
  • sigillum-js/ui
  • sigillum-js/vue

Readme

sigillum-js

Session recording for the web. Record user behavior, replay it, debug faster.

npm version npm downloads TypeScript license

English | 中文


What it does

Records the entire user session so you can replay every step of user behavior. Data stays on your own servers.

Installation

npm install sigillum-js
yarn / pnpm
yarn add sigillum-js
# or
pnpm add sigillum-js

Quick Start

import { getRecorder } from 'sigillum-js';

const recorder = getRecorder({
  onUpload: async (data) => {
    await fetch('/api/recordings', {
      method: 'POST',
      body: JSON.stringify(data),
    });
    return { success: true };
  },
});

recorder.start();

// Later — stop and upload
await recorder.stop();

That's it. The recorder captures everything automatically — mouse movement, scrolling, inputs, and route changes. When stop() is called, data is uploaded via your onUpload callback.

Local-only mode (no upload)

For debugging workflows where users export recordings manually:

const recorder = getRecorder({ debug: true });

recorder.start();
// ... user reproduces the bug ...
await recorder.stop();

const data = recorder.exportRecording();
downloadAsJson(data); // your download helper

Framework Integrations

Framework Import Path Key Exports
Vanilla JS sigillum-js getRecorder(), resetRecorder(), isRecorderInitialized()
React 16.8+ sigillum-js/react useSessionRecorder(), useAutoRecord()
Vue 3+ sigillum-js/vue createSigillumPlugin(), useSessionRecorder(), useAutoRecord()
WeChat Mini Program beta sigillum-js/miniapp createMiniAppRecorder(), getSigillum()
Taro 3.0+ beta sigillum-js/miniapp/taro createTaroRecorder(), getTaroSigillum()
React Example
import { useAutoRecord } from 'sigillum-js/react';

function App() {
  const { status, sessionId, addTag, identify } = useAutoRecord({
    onUpload: async (data) => {
      await fetch('/api/recordings', { method: 'POST', body: JSON.stringify(data) });
      return { success: true };
    },
  });

  identify('user-123', { plan: 'pro' });

  return <div>Status: {status}</div>;
}
Vue 3 Example
// main.ts
import { createApp } from 'vue';
import { createSigillumPlugin } from 'sigillum-js/vue';

const app = createApp(App);
app.use(createSigillumPlugin({
  onUpload: async (data) => {
    await fetch('/api/recordings', { method: 'POST', body: JSON.stringify(data) });
    return { success: true };
  },
  autoStart: true,
}));
app.mount('#app');
<script setup>
import { inject, onUnmounted, ref } from 'vue';
import { useAutoRecord } from 'sigillum-js/vue';

const { status, sessionId, addTag } = useAutoRecord(inject, onUnmounted, { ref });
</script>

<template>
  <div>Status: {{ status.value }}</div>
</template>

Replay UI

Built-in React components for replaying recordings:

import { ReplayPlayer, ReplayPage } from 'sigillum-js/ui';

<ReplayPlayer data={recordingData} />

// Full page with session info
<ReplayPage data={recordingData} showInfo={true} />
Replay Config

Pass config to customize replay behavior. Common rrweb Replayer options are available as first-class fields; for anything else, use the replayerConfig passthrough.

<ReplayPlayer
  data={recordingData}
  config={{
    speed: 2,
    autoPlay: true,
    showController: true,
    skipInactive: true,

    // rrweb Replayer options
    UNSAFE_replayCanvas: true,   // Required when recordCanvas was enabled
    mouseTail: false,            // Hide mouse trail
    pauseAnimation: true,        // Pause CSS animations during pause
    useVirtualDom: false,
    liveMode: false,
    triggerFocus: true,
    insertStyleRules: ['body { background: #fff; }'],
    unpackFn: (e) => e,          // Paired with packFn during recording

    // Passthrough for any other rrweb Replayer option not listed above
    replayerConfig: {
      // e.g. blockClass, loadTimeout, showWarning, etc.
    },
  }}
/>

Note: events, width, and height are managed internally and cannot be overridden via config or replayerConfig.

API Reference

const recorder = getRecorder(options);

// Lifecycle
recorder.start();
await recorder.stop();
recorder.pause();
recorder.resume();

// Data
recorder.exportRecording();     // Export after stop (events + metadata + summary)
recorder.clearRecording();      // Free memory

// Tags & Identity
recorder.addTag(name, data);
recorder.identify(userId, traits?);

// Status
recorder.getStatus();           // 'idle' | 'recording' | 'paused' | 'stopped'
recorder.getSessionId();
recorder.getEventCount();
recorder.getEstimatedSize();
recorder.getSummary();          // { clickCount, inputCount, scrollCount, routeChanges, ... }

// Cleanup
recorder.destroy();
resetRecorder();
Configuration
const recorder = getRecorder({
  // Upload (optional — without it, runs in local-only mode)
  onUpload: async (data) => { return { success: true }; },

  // Field mapping (adapt to your backend schema)
  fieldMapping: [['sessionId', 'id'], ['events', 'content', JSON.stringify, JSON.parse]],
  beforeUpload: (data) => ({ ...data, userId: getCurrentUserId() }),

  // Enable condition
  enabled: () => user.isVIP || Math.random() < 0.1,

  // Crash recovery cache
  cache: { enabled: true, saveInterval: 5000, maxItems: 10, maxAge: 604800000 },

  // Chunked upload (for long recordings)
  chunkedUpload: { enabled: true, interval: 60000 },
  onChunkUpload: async (chunk) => { return { success: true }; },

  // Callbacks
  onEventEmit: (event, count) => {},
  onError: (error) => {},
  onStatusChange: (status, prev) => {},

  // Limits
  maxEvents: 50000,
  maxDuration: 1800000,  // 30 min
  maxRetries: 3,

  // Privacy (mask inputs, block elements, etc.)
  rrwebConfig: {
    privacy: {
      blockSelector: '.credit-card-form, [data-private]',
      maskAllInputs: true,
    },
    slimDOMOptions: 'all',
  },

  // Misc
  uploadOnUnload: true,
  beaconUrl: '/api/beacon',
  debug: false,
});

Compatibility

Browser Version
Chrome 64+
Firefox 69+
Safari 12+
Edge 79+ (Chromium)
iOS Safari 12+
IE Not supported
Framework Version Import Path
React 16.8+ sigillum-js/react
Vue 3.0+ sigillum-js/vue
Next.js 12+ Via React integration
Nuxt 3+ Via Vue integration

Mini Program Support v2.0-beta

Beta Testing — Install via npm install sigillum-js@beta. Only WeChat native and Taro are supported at this time. APIs may change between beta releases.

Platform Version Import Path Status
WeChat Mini Program Base library >= 1.4.0 (recommended >= 2.1.0) sigillum-js/miniapp Beta
Taro 3.0.0+ sigillum-js/miniapp/taro Beta
Alipay / TikTok / Baidu / QQ Planned

v2.0 brings semantic user behavior tracking to mini programs (where rrweb cannot work):

  • Three monitoring presetslite (tap + page only), standard (+ input, scroll, swipe), full (+ touch stream, scroll depth)
  • Configurable throttle — per-event-type throttle intervals, overridable via monitoring.throttle
  • Privacy configurablemaskInputs: true masks all input values before they leave the device (see Privacy Protection)
  • Semantic action chain replaybuildActionChain() + ActionChainPlayer for human-readable session review
  • Taro auto-capture — zero manual tracking code, monkey-patches dispatchEvent
  • Unified recording protocolSigillumRecording envelope format with auto-detection for both Web and MiniApp data

See the Mini Program Integration Guide for full documentation.

Also Check Out

If you need error tracking, log management, and performance monitoring, check out aemeath-js — a lightweight, plugin-based frontend logging & monitoring SDK.

Together, sigillum-js (session replay) + aemeath-js (logging & monitoring) provide a complete frontend observability solution — all data stays on your own servers.

Contributing

Issues and feature requests are welcome! Feel free to open an issue.

License

MIT © TieriaSail


Built with AI assistance.