The Webrec SDK is a lightweight JavaScript library that captures session recordings, errors, and analytics data from your web application. This guide covers installation, configuration, and the full API reference.
Install the SDK from npm (available once published):
npm install @webrec/sdk
# or with yarn
yarn add @webrec/sdk
# or with pnpm
pnpm add @webrec/sdkNote: The npm package will be available once published. In the meantime, use the script tag method below.
Then import and initialize in your application entry point:
import { WebRec } from '@webrec/sdk';
WebRec.init({
apiKey: 'your-project-api-key',
});Include the SDK via a script tag. This is the recommended method until the npm package is published, and is useful for sites that don't use a JavaScript bundler.
<script src="https://api.webrec.app/v1/webrec.min.js"></script>
<script>
WebRec.init({
apiKey: 'your-project-api-key',
});
</script>After the SDK is published to npm, you can also use CDN links:
<!-- Via unpkg -->
<script src="https://unpkg.com/@webrec/sdk@latest/dist/webrec.umd.js"></script>
<!-- Or via jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/@webrec/sdk/dist/webrec.umd.js"></script>The script tag version loads asynchronously to avoid blocking page rendering.
Pass a configuration object to WebRec.init(). All options except apiKey are optional.
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | (required) | Your project API key from the Webrec dashboard. |
endpoint | string | "https://api.webrec.app/v1" | Custom API endpoint for self-hosted or proxy setups. |
sampleRate | number | 100 | Percentage of traffic to record (0-100). |
maskAllInputs | boolean | true | Mask all input field values in recordings. |
blockClass | string | "wr-block" | CSS class to exclude elements from recording. |
blockSelector | string | "[data-wr-block]" | CSS selector for elements to exclude from recording. |
ignoreClass | string | "wr-ignore" | CSS class to ignore interactions on elements. |
ignoreSelector | string | "[data-wr-ignore]" | CSS selector for elements to ignore interactions on. |
captureConsole | boolean | true | Capture console.log, warn, error output. |
captureNetwork | boolean | true | Capture network requests and responses. |
captureErrors | boolean | true | Capture JavaScript errors and stack traces. |
recordCanvas | boolean | false | Record canvas/WebGL elements. Increases CPU usage. |
collectFonts | boolean | true | Collect fonts used on the page for accurate replay. |
respectDoNotTrack | boolean | true | Respect the browser Do Not Track setting. |
sessionTimeout | number | 1800000 | Session timeout in milliseconds (default 30 minutes). |
batchSize | number | 50 | Number of events to batch before sending. |
flushInterval | number | 5000 | Interval in milliseconds between flushes. |
maxQueueSize | number | 2000 | Max events to hold in memory before evicting oldest. |
maxRetries | number | 3 | Max retry attempts for failed flushes. |
minTimeOnPage | number | 0 | Minimum time in ms on page before recording starts. |
minSessionDuration | number | 0 | Minimum session duration in seconds before data is sent. |
startDelay | number | 0 | Delay in ms before recording starts after init. |
debug | boolean | false | Enable verbose debug logging to console. |
You can also pass a privacy object for granular control:
WebRec.init({
apiKey: 'wr_proj_abc123',
privacy: {
maskInputs: true, // Mask form input values (default true)
maskTextContent: false, // Mask all text content (default false)
blockSelectors: ['.secret-panel'],
ignoreSelectors: ['.analytics-only'],
},
});Control the sampling of high-frequency events:
WebRec.init({
apiKey: 'wr_proj_abc123',
sampling: {
mousemove: 50, // Sample mousemove every 50ms (or true/false)
scroll: 150, // Sample scroll every 150ms
input: 'last', // Capture 'last' input value or 'all' keystrokes
},
});Control which pages are recorded using URL patterns:
WebRec.init({
apiKey: 'wr_proj_abc123',
ignoreUrls: ['/admin.*', '/internal.*'], // Skip these URLs
allowUrls: ['/app.*', '/checkout.*'], // Only record these URLs
});WebRec.init({
apiKey: 'wr_proj_abc123',
sampleRate: 50, // Record 50% of traffic
maskAllInputs: true,
captureConsole: true,
captureNetwork: true,
captureErrors: true,
respectDoNotTrack: true,
blockClass: 'wr-block',
sessionTimeout: 1800000, // 30 minutes
debug: false,
});Initialize the SDK with the given configuration. Must be called once before any other API methods.
WebRec.init({
apiKey: 'wr_proj_abc123',
});Associate the current session with a known user. Call this after the user logs in. Traits are optional metadata attached to the user profile.
WebRec.identify('user_42', {
name: 'Jane Doe',
email: 'jane@example.com',
plan: 'pro',
});Track a custom event with optional properties. Events appear as markers in the session timeline and can be used for funnel analysis.
WebRec.track('purchase_completed', {
orderId: 'ORD-1234',
total: 59.99,
currency: 'USD',
});Manually start recording. Only needed if you set autoStart: false in the configuration or have called stop(). Useful for starting recording only after user consent.
// Start recording after consent
document.getElementById('consent-btn')
.addEventListener('click', () => {
WebRec.start();
});Stop the current recording. The session data collected so far will still be uploaded. You can call start() again to resume recording.
// Stop recording when user navigates to sensitive page
WebRec.stop();Completely tear down the SDK, remove all event listeners, and stop recording. Use this for cleanup in single-page applications when unmounting. After calling destroy(), you must call init() again to use the SDK.
// Cleanup on app unmount
WebRec.destroy();Returns the current session ID, or null if the SDK is not initialized. Useful for correlating session recordings with your own backend logs.
const sessionId = WebRec.getSessionId();
console.log('Webrec session:', sessionId);
// Attach to support tickets, bug reports, etc.
fetch('/api/support', {
method: 'POST',
body: JSON.stringify({
message: 'Help!',
webrecSession: sessionId,
}),
});Returns a direct URL to the current session replay in the Webrec dashboard. Useful for linking from internal tools or error trackers.
const url = WebRec.getSessionUrl();
// e.g. "https://app.webrec.app/projects/xxx/sessions/yyy"Returns true if the SDK is currently recording, false otherwise.
if (WebRec.isRecording()) {
console.log('Recording is active');
}Webrec includes an in-app survey widget that lets you collect feedback directly from your users. Surveys are configured in the dashboard and delivered automatically via the SDK.
Surveys are enabled by default when you install the SDK. The widget loads asynchronously and will not affect page performance. You can disable surveys via configuration:
WebRec.init({
apiKey: 'wr_proj_abc123',
surveys: false, // Disable the survey widget
});Create surveys in the Webrec dashboard under Surveys. Supported question types:
Target surveys by URL, user properties, or behaviour. Configure targeting rules in the dashboard:
identify()The SDK emits events you can listen to for custom integrations:
WebRec.on('survey:shown', (survey) => {
console.log('Survey shown:', survey.id);
});
WebRec.on('survey:completed', (survey, response) => {
console.log('Survey completed:', survey.id, response);
});
WebRec.on('survey:dismissed', (survey) => {
console.log('Survey dismissed:', survey.id);
});Webrec automatically detects user frustration signals and surfaces them in the dashboard. Frustration detection requires no additional configuration -- it works out of the box.
A dead click is a click on an element that produces no visible response -- no navigation, no DOM change, no network request. Dead clicks often indicate broken buttons, missing links, or elements that look interactive but are not.
Dead clicks are detected automatically and appear in the session timeline, session list filters, and heatmaps. You can filter sessions by dead click count in the dashboard.
When a click triggers a JavaScript error within a short time window, Webrec correlates the click with the error. Error clicks are highlighted in the session timeline and can be used as a filter in the session list.
Each session receives a frustration score -- a composite value calculated from dead clicks, rage clicks, error clicks, and other frustration signals. Use the frustration score to prioritise which sessions to review:
Frustration detection is enabled by default. You can customise thresholds:
WebRec.init({
apiKey: 'wr_proj_abc123',
frustration: {
deadClickTimeout: 1000, // ms to wait for response (default 1000)
rageClickThreshold: 3, // clicks in rapid succession (default 3)
rageClickWindow: 800, // ms window for rage clicks (default 800)
},
});Webrec is built with privacy as a core consideration. The SDK provides multiple mechanisms to control what data is captured.
By default, all input values (<input>, <textarea>, <select>) are masked in recordings and replaced with asterisks. This prevents accidental capture of passwords, personal data, and other sensitive information.
// Default behavior: all inputs masked
WebRec.init({ apiKey: '...', maskAllInputs: true });
// To unmask specific inputs, add the wr-unmask class:
// <input class="wr-unmask" type="text" placeholder="Search..." />Add the wr-block CSS class or data-wr-block attribute to any element to completely exclude it from recordings. Blocked elements are replaced with a placeholder in the replay.
<!-- Using CSS class -->
<div class="wr-block">
This content will not appear in recordings.
</div>
<!-- Using data attribute -->
<div data-wr-block>
<p>Sensitive information here</p>
</div>
<!-- Block specific sections -->
<section class="wr-block" id="payment-form">
<input type="text" name="card-number" />
<input type="text" name="cvv" />
</section>For maximum privacy, enable maskTextContent via the privacy config to replace all visible text with generic characters. This is useful for applications handling highly sensitive data.
WebRec.init({
apiKey: '...',
privacy: {
maskTextContent: true,
// You can still see page structure and user behavior,
// but all text content is masked.
},
});Network capture records request URLs and status codes by default. Request and response bodies are not captured unless you explicitly use the captureNetwork option. You can also use ignoreUrls to filter which endpoints are captured.
WebRec.init({
apiKey: '...',
captureNetwork: true,
ignoreUrls: [
'/api/auth.*', // Exclude auth endpoints
'stripe\.com', // Exclude payment URLs
],
});If you need to obtain user consent before recording, set startDelay or use start() manually after consent is given. The SDK does not start recording until you call start().
// Initialize but don't record yet
WebRec.init({
apiKey: '...',
});
// The SDK does not set cookies by default.
// It uses sessionStorage for the session ID.
// Call stop() immediately if you want to wait for consent:
WebRec.stop();
// Later, after user consents:
function onConsentGranted() {
WebRec.start();
}The SDK respects the browser's Do Not Track setting by default. If a user has enabled DNT, the SDK will not record. You can override this behavior:
WebRec.init({
apiKey: '...',
respectDoNotTrack: false, // Record even if DNT is enabled
});This section covers how to use Webrec in compliance with the General Data Protection Regulation (GDPR). As a Webrec customer, you are the data controller for end-user data collected via the SDK. Webrec acts as a data processor on your behalf.
Before deploying the Webrec SDK, ensure you have a valid legal basis for processing end-user data. Common approaches include:
WebRec.start() after the user consents.To comply with data minimisation principles, use the SDK's masking features to avoid capturing personal data unnecessarily:
WebRec.init({
apiKey: 'wr_proj_abc123',
maskAllInputs: true, // Mask all form inputs
respectDoNotTrack: true, // Respect browser DNT
captureNetwork: true,
ignoreUrls: ['/api/auth.*'], // Don't capture auth requests
privacy: {
maskInputs: true,
maskTextContent: false,
blockSelectors: [
'.personal-data', // Block PII sections
'#payment-form', // Block payment forms
'[data-gdpr-sensitive]', // Block custom-marked elements
],
},
});Session recordings are retained according to your plan's retention period:
Recordings are automatically and permanently deleted after the retention period. You can also manually delete sessions from the dashboard or via the API.
As data controller, you are responsible for handling data subject requests from your end users. Webrec provides tools in the dashboard to:
Contact privacy@webrec.app if you need assistance processing data subject requests.
For GDPR compliance, you may need a Data Processing Agreement (DPA) with Webrec. Our DPA is included in the Terms of Service. It covers the obligations of both parties, sub-processors, data security measures, and breach notification procedures.
Webrec Cloud stores data in Google Cloud Platform's europe-west2 region (London, UK). For self-hosted deployments, you control exactly where data is stored.
In React applications, initialize the SDK in a top-level component or layout. Use an effect to ensure it runs only on the client.
'use client';
import { useEffect } from 'react';
import { WebRec } from '@webrec/sdk';
export default function RootLayout({ children }) {
useEffect(() => {
WebRec.init({
apiKey: process.env.NEXT_PUBLIC_WEBREC_KEY,
});
return () => {
WebRec.destroy();
};
}, []);
return <html><body>{children}</body></html>;
}In Vue applications, initialize in a plugin or in your main app file.
import { WebRec } from '@webrec/sdk';
export default defineNuxtPlugin(() => {
WebRec.init({
apiKey: useRuntimeConfig().public.webrecKey,
});
});For vanilla JavaScript applications, initialize the SDK after the DOM is ready.
import { WebRec } from '@webrec/sdk';
document.addEventListener('DOMContentLoaded', () => {
WebRec.init({
apiKey: 'wr_proj_abc123',
});
});Webrec provides APIs for managing custom dashboards, exporting data, and interacting with surveys programmatically.
Custom dashboards are created and managed in the Webrec web application. Drag and drop widgets to build analytics views tailored to your team. Available widget types:
Export session, error, and analytics data as CSV files from the dashboard. You can also trigger exports programmatically via the REST API:
// Export sessions as CSV
GET /v1/projects/:projectId/export/sessions?format=csv
&from=2026-01-01&to=2026-03-01
// Export errors as CSV
GET /v1/projects/:projectId/export/errors?format=csv
&from=2026-01-01&to=2026-03-01
// Export analytics data as CSV
GET /v1/projects/:projectId/export/analytics?format=csv
&metric=pageviews&from=2026-01-01&to=2026-03-01
// Headers
Authorization: Bearer <your-api-key>Create and manage surveys via the REST API. Useful for automating survey creation or integrating with your CI/CD pipeline:
// List surveys
GET /v1/projects/:projectId/surveys
// Create a survey
POST /v1/projects/:projectId/surveys
{
"name": "Feature satisfaction",
"type": "rating",
"question": "How satisfied are you with this feature?",
"targeting": {
"url_contains": "/dashboard"
}
}
// Get survey responses
GET /v1/projects/:projectId/surveys/:surveyId/responses
// Headers
Authorization: Bearer <your-api-key>// After successful authentication
async function onLogin(user) {
WebRec.identify(user.id, {
name: user.name,
email: user.email,
plan: user.subscription.plan,
company: user.company?.name,
});
}// Track each step of a checkout funnel
WebRec.track('checkout_started');
// ... user fills in shipping
WebRec.track('shipping_completed', { method: 'express' });
// ... user enters payment
WebRec.track('payment_entered');
// ... order confirmed
WebRec.track('order_completed', {
orderId: order.id,
total: order.total,
items: order.items.length,
});// Errors are captured automatically, but you can
// attach the session ID to your own error reports:
window.addEventListener('error', (event) => {
myErrorTracker.report({
message: event.message,
stack: event.error?.stack,
webrecSessionId: WebRec.getSessionId(),
webrecSessionUrl: WebRec.getSessionUrl(),
});
});// React example with cleanup
import { useEffect } from 'react';
import { WebRec } from '@webrec/sdk';
function App() {
useEffect(() => {
WebRec.init({ apiKey: 'wr_proj_abc123' });
return () => WebRec.destroy();
}, []);
return <div>...</div>;
}If you have questions or run into issues, reach out to us at support@webrec.app or open an issue on GitHub.