@trapify-tech/browser
v0.1.2
Published
Trapify error tracking SDK for browser and Node.js
Maintainers
Readme
@trapify-tech/browser
Error tracking SDK for browser and Node.js. Captures unhandled exceptions and sends them to Trapify with full stack traces, breadcrumbs, and user context.
Table of contents
Install
npm install @trapify-tech/browserOr via CDN (no build step):
<script src="https://cdn.jsdelivr.net/npm/@trapify-tech/browser/dist/trapify.min.js"></script>
<script>
Trapify.init({ dsn: 'your-32-char-dsn-key' });
</script>Browser SDK
Import from the package root.
Quick start
import { init } from '@trapify-tech/browser';
init({ dsn: 'your-32-char-dsn-key' });Call init once at application startup (e.g. main.ts). Unhandled errors and promise rejections are captured automatically.
Configuration
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| dsn | string | required | 32-character hex key from your Trapify project settings |
| environment | string | null | Attached to every event ('production', 'staging', etc.) |
| release | string | null | App version string |
| maxBreadcrumbs | number | 50 | Max breadcrumbs retained in memory |
| autoCapture | boolean | true | Capture window.onerror and unhandledrejection |
| captureConsole | boolean | true | Capture console.error/warn/info/log as breadcrumbs |
| captureFetch | boolean | true | Capture fetch requests as breadcrumbs |
| debug | boolean | false | Log SDK errors to console |
| beforeSend | function | — | Hook called before every send — return null to drop |
| endpoint | string | Trapify production | Override the ingest URL (useful for testing) |
init({
dsn: 'your-32-char-dsn-key',
environment: 'production',
release: '1.0.0',
beforeSend: (event) => {
if (event.environment === 'development') return null; // drop dev errors
return event;
},
});Manual capture
import { captureException, captureMessage } from '@trapify-tech/browser';
try {
riskyOperation();
} catch (err) {
captureException(err as Error);
}
captureMessage('Checkout flow started', 'info');User context
import { setUser } from '@trapify-tech/browser';
setUser({ id: 'u_123', email: '[email protected]', username: 'alice' });
// On logout
setUser(null);Tags
import { setTag } from '@trapify-tech/browser';
setTag('plan', 'pro');
setTag('region', 'eu-west');Tags are attached to every subsequent event.
Breadcrumbs
import { addBreadcrumb } from '@trapify-tech/browser';
addBreadcrumb({
timestamp: new Date().toISOString(),
type: 'ui',
category: 'click',
message: 'Checkout button clicked',
});Console calls, fetch requests, and navigation events are captured automatically when captureConsole, captureFetch, and navigation patching are enabled.
beforeSend hook
init({
dsn: '...',
beforeSend: (event) => {
// Scrub sensitive data
if (event.user) {
event = { ...event, user: { ...event.user, email: '[redacted]' } };
}
// Drop noisy errors
if (event.exception?.value?.includes('ResizeObserver')) return null;
return event;
},
});Shutdown
import { close } from '@trapify-tech/browser';
close(); // removes all global handlers — useful in tests or SSR teardownDirect client usage
For multiple isolated clients (e.g. different DSNs in a monorepo):
import { TrapifyClient } from '@trapify-tech/browser';
const client = new TrapifyClient({ dsn: 'your-dsn', autoCapture: false });
client.captureException(new Error('Something went wrong'));
client.close();Framework examples
React / Vite
// src/main.tsx
import { init } from '@trapify-tech/browser';
init({
dsn: import.meta.env.VITE_TRAPIFY_DSN,
environment: import.meta.env.MODE,
release: import.meta.env.VITE_APP_VERSION,
});Next.js (App Router)
// instrumentation.ts
export async function register() {
if (typeof window !== 'undefined') {
const { init } = await import('@trapify-tech/browser');
init({ dsn: process.env.NEXT_PUBLIC_TRAPIFY_DSN! });
}
}Node.js SDK
Import from the /node subpath. This entry point uses the native https module (no fetch dependency) and adds server-specific helpers: withTrapify, errorHandler, and flush.
import { init, captureException } from '@trapify-tech/browser/node';Quick start (Node)
import { init } from '@trapify-tech/browser/node';
init({
dsn: process.env.TRAPIFY_DSN!,
environment: 'production',
autoCapture: true, // hooks process.uncaughtException + unhandledRejection
});Configuration (Node)
All browser options are supported, plus:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| captureConsole | boolean | false | Capture console calls as breadcrumbs (default off — high noise in server logs) |
Firebase Cloud Functions
Use withTrapify to wrap any async Cloud Function handler. It captures unexpected errors (those that would surface as internal to the client) and re-throws them. Intentional HttpsError throws are passed through without capture.
// functions/src/billing/createCheckoutSession.ts
import { onCall, HttpsError } from 'firebase-functions/v2/https';
import { defineSecret } from 'firebase-functions/params';
import { init, withTrapify } from '@trapify-tech/browser/node';
const TRAPIFY_DSN = defineSecret('TRAPIFY_DSN');
export const createCheckoutSession = onCall(
{ secrets: [TRAPIFY_DSN] },
withTrapify(async (request) => {
// init inside the handler — secrets are only available at invocation time
init({ dsn: TRAPIFY_DSN.value(), environment: 'production', autoCapture: false });
if (!request.auth) throw new HttpsError('unauthenticated', 'Sign in required');
// ... business logic
}),
);withTrapify works with any async function, not just Cloud Functions:
import { withTrapify } from '@trapify-tech/browser/node';
const handler = withTrapify(async (event: SQSEvent) => {
// process event
});Express error middleware
Add errorHandler() as the last middleware in your Express app. It captures the error and calls next(err) to continue the chain.
import express from 'express';
import { init, errorHandler } from '@trapify-tech/browser/node';
init({ dsn: process.env.TRAPIFY_DSN!, environment: 'production' });
const app = express();
app.use('/api', router);
// Must be last — after all routes
app.use(errorHandler());Flushing before process exit
In serverless environments the process may be frozen before in-flight HTTP requests complete. Call flush() after sending events and before returning from the handler.
import { captureException, flush } from '@trapify-tech/browser/node';
try {
await riskyOperation();
} catch (err) {
captureException(err as Error);
await flush(2000); // wait up to 2s for the event to be sent
throw err;
}withTrapify calls flush automatically before re-throwing, so you don't need to do this manually when using the wrapper.
Publishing
From the repo root:
# Bump version (patch / minor / major)
npm run sdk:release patch
# Publish to npm
npm run sdk:publishsdk:publish runs typecheck → tests → build via prepublishOnly before the package is uploaded. A broken SDK cannot be published.
