JSPM

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

A session recording library for user behavior replay and bug reproduction

Package Exports

  • sigillum-js
  • sigillum-js/react
  • 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()
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} />

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

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.