Skip to content

Web SDK

An embeddable JavaScript plugin for capturing screen recordings with rich context (user identity, technical state, DOM snapshot) for support and feedback purposes.

Features

  • Screen recording with audio
  • Automatic context capture:
    • User identity and session info
    • Technical state (URL, browser, console logs, network requests)
    • DOM snapshot with key elements
    • JavaScript errors and performance metrics
  • Clean modal UI for user consent
  • Automatic upload to Horus API
  • Privacy-conscious with user consent

Installation

As NPM Package

bash
npm install @horus/support
typescript
import { HorusSupport } from '@horus/support';

As Standalone Script

html
<script src="https://tryhorus.io/horusSupport.js"></script>

Quick Start

Basic Setup

typescript
import { HorusSupport } from '@horus/support';

// Initialize plugin with embed token (recommended)
await HorusSupport.init({
  embedToken: 'proj_abc123...',
  userInfo: {
    email: 'user@example.com',
    name: 'John Doe',
    id: 'user-123',
  },
  // Custom message for mobile users or incompatible browsers
  fallbackMessage: 'Screen recording is unavailable on mobile. Please email your issue to <a href="mailto:support@example.com">support@example.com</a>',
  fallbackTitle: 'Recording Unavailable',
});

// Trigger capture
HorusSupport.captureIssue();

As Standalone Script

html
<script src="https://tryhorus.io/horusSupport.js"></script>
<script>
  window.HorusSupport.init({
    embedToken: 'proj_abc123...',
    fallbackMessage: 'Screen recording is unavailable on this device. Please email your issue to <a href="mailto:support@example.com">support@example.com</a>',
  });
</script>

<button onclick="window.HorusSupport.captureIssue()">
  Report Issue
</button>

Recording Flow

  1. User triggers capture - Call HorusSupport.captureIssue() from a button or link
  2. Consent modal appears - User sees what will be captured and can proceed
  3. Screen recording starts - Browser shows recording indicator
  4. User demonstrates issue - They show the problem in their workflow
  5. User stops recording - Recording is automatically uploaded
  6. Context is attached - Technical state, DOM snapshot, and metadata are included

API Reference

HorusSupport.init(config)

Initialize the plugin with configuration.

ParameterTypeRequiredDescription
embedTokenstringYes (recommended)Embed token from project settings
recordingLinkIdstringLegacyRecording link ID where recordings will be submitted
apiUrlstringNoAPI base URL (defaults to 'https://tryhorus.io')
captureOptionsobjectNoWhat context to capture
userInfoobjectNoPre-filled user information
customMetadataobjectNoCustom metadata to include
privacyPolicyUrlstringNoPrivacy policy URL
buttonTextstringNoCustom button text
fallbackMessagestringNoCustom message for mobile/incompatible browsers (supports HTML)
fallbackTitlestringNoTitle for fallback message modal

HorusSupport.captureIssue(description?)

Open modal to capture an issue/feedback.

ParameterTypeRequiredDescription
descriptionstringNoPre-filled description

Returns: Promise<void>

HorusSupport.stopRecording()

Stop the current recording and upload.

Returns: Promise<void>

HorusSupport.cancelRecording()

Cancel the current recording.

Returns: void

HorusSupport.getState()

Get current plugin state (for debugging).

Returns: Readonly<PluginState>

HorusSupport.reset()

Reset plugin state (for testing).

Returns: void

Context Capture

The plugin automatically captures rich context to help debug issues:

User Identity

  • Email, name, user ID
  • Session ID
  • Timestamp

Technical State

  • Current URL and page title
  • Browser info (user agent, platform, device memory)
  • Viewport size
  • Console logs (last 50 by default)
  • Network requests (last 20 by default)
  • JavaScript errors
  • Performance metrics (TTFB, FCP, LCP)

DOM Snapshot

  • Sanitized HTML (removes passwords, scripts)
  • Key elements in viewport (buttons, links, inputs)
  • Form data (sanitized)

Privacy

  • Users must explicitly consent before recording starts
  • Passwords and hidden input values are redacted
  • Script content is removed from DOM snapshots
  • Privacy policy link can be displayed in modal
  • All capture can be disabled via captureOptions

Customizing Capture Options

typescript
HorusSupport.init({
  embedToken: 'proj_abc123...',
  captureOptions: {
    // Enable/disable specific capture types
    consoleLogs: true,      // Capture console logs
    networkRequests: true,  // Capture network requests
    domSnapshot: true,      // Capture DOM snapshot
    userAgent: true,        // Capture browser info
    performance: true,      // Capture performance metrics

    // Limits
    maxConsoleLogs: 50,     // Max console entries
    maxNetworkRequests: 20, // Max network entries
  }
});

Browser Support

BrowserSupport Level
Chrome/EdgeFull support (WebM/VP9)
FirefoxFull support (WebM/VP8)
Safari DesktopSupported (Safari 14.1+, MP4/H.264)
Mobile browsersNot supported - shows fallback message

File Size Limits

Upload TypeSize
Direct upload< 10MB
Multipart upload≥ 10MB (uploaded in 5MB chunks)

Troubleshooting

Recording doesn't start

  1. Check browser compatibility (Chrome, Firefox, Safari 14.1+)
  2. Ensure HTTPS (required for screen capture API)
  3. Verify the user granted screen capture permission

No audio in recording

  1. Check that microphone permission was granted
  2. Ensure the tab has audio focus
  3. Verify no other app is using the microphone exclusively

Upload fails

  1. Verify network connectivity
  2. Check that embedToken is valid
  3. Check browser console for error details

Context not captured

  1. Ensure captureOptions doesn't disable the capture type
  2. Check that initialization completed before capture
  3. Verify the capture APIs are available in the browser

Technical Notes

Console Log Interception

The plugin intercepts console.log, console.warn, console.error, etc. to capture logs. This is done automatically on initialization.

Network Request Interception

The plugin intercepts fetch and XMLHttpRequest to capture network requests. This is also done automatically on initialization.

DOM Sanitization

When capturing DOM snapshots:

  • Password input values are replaced with [REDACTED]
  • Script content is removed
  • Hidden inputs with sensitive names are sanitized
  • Data URIs are truncated to prevent large payloads

Released under the MIT License.