Official Browser SDK for Checkend error monitoring. Capture and report errors from browser applications with automatic error handling and context tracking.
- Zero dependencies - Lightweight, no external dependencies
- Automatic error capture - Captures
window.onerrorand unhandled promise rejections - Context tracking - Attach user info and custom context to errors
- Sensitive data filtering - Automatically scrubs passwords, tokens, etc.
- TypeScript support - Full TypeScript definitions included
- Testing utilities - Mock SDK for unit testing
npm install @checkend/browser
# or
yarn add @checkend/browser
# or
pnpm add @checkend/browserimport Checkend from '@checkend/browser'
Checkend.configure({
apiKey: 'your-ingestion-key',
// Optional: custom endpoint
// endpoint: 'https://checkend.example.com',
})
// That's it! Unhandled errors are now automatically captured.import { notify, notifySync } from '@checkend/browser'
try {
// risky code
} catch (error) {
notify(error as Error)
}
// With additional context
notify(error, {
context: { orderId: 123 },
user: { id: 'user-1', email: 'user@example.com' },
tags: ['checkout', 'payment'],
fingerprint: 'custom-grouping-key',
})
// Synchronous sending (returns promise)
const response = await notifySync(error)import Checkend from '@checkend/browser'
Checkend.configure({
// Required
apiKey: 'your-ingestion-key',
// Optional - Checkend server URL (default: https://app.checkend.io)
endpoint: 'https://checkend.example.com',
// Optional - Environment name (auto-detected from hostname)
environment: 'production',
// Optional - Enable/disable reporting (default: true in production/staging)
enabled: true,
// Optional - Capture unhandled errors (default: true)
captureUnhandled: true,
// Optional - Capture unhandled promise rejections (default: true)
captureUnhandledRejections: true,
// Optional - Exceptions to ignore
ignoredExceptions: ['MyCustomNotFoundError', /^Network/],
// Optional - Keys to filter from context/request data
filterKeys: ['creditCard', 'ssn'],
// Optional - Callbacks before sending (return false to skip)
beforeNotify: [
(notice) => {
notice.context.deployVersion = window.DEPLOY_VERSION
return true // Return true to send, false to skip
},
],
// Optional - Request timeout in milliseconds (default: 15000)
timeout: 15000,
// Optional - Maximum notices to queue (default: 100)
maxQueueSize: 100,
// Optional - Use sendBeacon API (default: true)
useSendBeacon: true,
// Optional - Enable debug logging (default: false)
debug: false,
})import { setContext, setUser, clear } from '@checkend/browser'
// Set context that will be included with all errors
setContext({
accountId: 'acc-123',
featureFlag: 'new_checkout',
})
// Track current user
setUser({
id: 'user-1',
email: 'user@example.com',
name: 'Jane Doe',
})
// Clear context (e.g., on logout)
clear()Use the Testing module to capture notices without sending them:
import Checkend, { notify } from '@checkend/browser'
import { Testing } from '@checkend/browser/testing'
describe('Error handling', () => {
beforeEach(() => {
Testing.setup()
Checkend.configure({ apiKey: 'test-key' })
})
afterEach(() => {
Testing.teardown()
Checkend.reset()
})
test('reports errors', () => {
notify(new Error('Test error'))
expect(Testing.notices).toHaveLength(1)
expect(Testing.lastNotice?.errorClass).toBe('Error')
expect(Testing.lastNotice?.message).toBe('Test error')
})
})| Method | Description |
|---|---|
Testing.setup() |
Enable test mode, intercept network calls |
Testing.teardown() |
Restore normal mode, clear notices |
Testing.notices |
Array of captured Notice objects |
Testing.lastNotice |
Most recent notice |
Testing.firstNotice |
First captured notice |
Testing.noticeCount() |
Number of captured notices |
Testing.hasNotices() |
True if any notices captured |
Testing.clearNotices() |
Clear captured notices |
The SDK automatically filters sensitive data from context and request data.
Default filtered keys: password, secret, token, api_key, authorization, credit_card, cvv, ssn
Add custom keys:
Checkend.configure({
apiKey: 'your-key',
filterKeys: ['socialSecurityNumber', 'bankAccount'],
})Some exceptions don't need to be reported:
Checkend.configure({
apiKey: 'your-key',
ignoredExceptions: [
// By exact message
'ResizeObserver loop limit exceeded',
// By regex pattern
/^Script error/,
],
})- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
The SDK uses modern APIs like fetch, Promise, and Blob. For older browsers, you may need polyfills.
- No runtime dependencies
- Works in all modern browsers
- TypeScript 5.0+ (for types)
# Install dependencies
npm install
# Build
npm run build
# Run tests (52 tests)
npm test
# Run tests in watch mode
npm run test:watch
# Type check
npm run typecheckThe SDK includes comprehensive tests using Vitest:
| Test File | Tests | Description |
|---|---|---|
test/configuration.test.ts |
15 | Config options, validation, ignored exceptions |
test/notice.test.ts |
12 | Notice creation, payload format, truncation |
test/sanitize.test.ts |
8 | Sensitive data filtering, deep nesting |
test/index.test.ts |
17 | Main API: notify, context, user, callbacks |
Run a specific test file:
npm test -- test/configuration.test.tsMIT License. See LICENSE for details.