5xx-sdk
v1.5.0
Published
Lightweight error tracking SDK for JavaScript/TypeScript applications
Maintainers
Readme
5xx-sdk
Lightweight error tracking and analytics SDK for JavaScript/TypeScript applications.
Installation
npm install 5xx-sdkOr copy the SDK files directly into your project.
Quick Start
Browser
import { FiveXXBrowser } from '5xx-sdk/browser';
const fivexx = new FiveXXBrowser({
apiKey: 'your-api-key',
endpoint: 'https://your-5xx-instance.com',
});
// Enable automatic capture of unhandled errors
fivexx.enableAutoCapture();
// Enable analytics (page views, visitor tracking, SPA navigation)
fivexx.enableAnalytics();
// Set user context (optional)
fivexx.setUser({
id: 'user-123',
email: '[email protected]',
});
// Manual error capture
try {
riskyOperation();
} catch (error) {
fivexx.captureError(error, { context: 'checkout' });
}
// Track custom events
fivexx.trackEvent('signup_completed', { plan: 'pro' });Node.js
import { FiveXXNode } from '5xx-sdk/node';
const fivexx = new FiveXXNode({
apiKey: 'your-api-key',
endpoint: 'https://your-5xx-instance.com',
exitOnFatalError: true,
});
// Enable automatic capture of uncaught exceptions
fivexx.enableAutoCapture();
// Wrap route handlers for automatic error capture (recommended)
// Works with Next.js, Express, Fastify, and any framework
export const GET = fivexx.wrapHandler(async (req: NextRequest) => {
const data = await db.user.findMany();
return NextResponse.json(data);
});
// Wrap async functions
const wrappedFn = fivexx.wrapAsync(async () => {
await someAsyncOperation();
});
// Manual capture
fivexx.captureError(new Error('Something went wrong'), {
userId: '123',
requestId: 'abc',
});
// Custom events from server code (queued, sent within 5 seconds)
fivexx.trackEvent('invoice_sent', { reason: 'renewal' });
await fivexx.flushEvents(); // before a serverless handler returns or the process exitsUniversal (works in both environments)
import { FiveXX } from '5xx-sdk';
const fivexx = new FiveXX({
apiKey: 'your-api-key',
endpoint: 'https://your-5xx-instance.com',
});
// Manual capture only
fivexx.captureError(new Error('Something went wrong'));
fivexx.captureMessage('User performed invalid action');API
FiveXX (Base Client)
new FiveXX(options: FiveXXOptions)
interface FiveXXOptions {
apiKey: string; // Your project's API key
endpoint: string; // Your 5xx instance URL
environment?: string; // Deprecated: ignored by the server (see below)
}Environment is a project setting. The server stamps every error with the project's own environment (set in the project's settings, "production" by default) and ignores the environment value in the payload, so it has no effect on stored errors or on grouping. environment and setEnvironment() are deprecated: they still compile and are still sent for compatibility, and will be removed in SDK 2.0. The browser client's "development" default on localhost and the Node client's NODE_ENV default have no server-side effect either. To separate staging from production, create one project per environment and give each deployment that project's API key.
Methods:
setEnvironment(env: string)- Deprecated, no server-side effect (environment is a project setting)setUser(user: User | null)- Set user context for errorscaptureError(error: Error, metadata?: object)- Capture an errorcaptureMessage(message: string, metadata?: object)- Capture a message
FiveXXBrowser
Extends FiveXX with browser-specific features.
Additional Methods:
enableAutoCapture()- Auto-capturewindow.onerrorandunhandledrejectiondisableAutoCapture()- Disable auto-captureenableAnalytics()- Enable page view tracking, SPA navigation, and visitor analyticstrackEvent(name: string, metadata?: object)- Track a custom event. BeforeenableAnalytics()the event is dropped with a one-time console warning (analytics is opt-in, so nothing is buffered before it)
Analytics behaviour:
- Opt-in via
enableAnalytics()— does not affect error tracking - Automatically tracks page views on load
- SPA support: patches
pushState/replaceStateand listens forpopstate - Batches analytics beacons and sends every 5 seconds
- Uses
navigator.sendBeacon()on page unload to prevent data loss, sending at most 60,000 UTF-8 bytes per flush (the browser's beacon quota is 64 KiB, shared by in-flight requests); anything over stays buffered for the next flush - Strips query params from URLs (keeps UTM params:
utm_source,utm_medium,utm_campaign, andref) - Privacy-friendly: no cookies, no fingerprinting. Visitor ID is derived server-side from IP + user agent + daily rotating salt
- No session analytics: visitors are daily uniques, not sessions. Versions up to 1.4.2 also sent a random per-page-load
sessionIdwith every batch; the server never stored it, so it was removed from the payload (the ingest endpoint still accepts and ignores it from older SDKs).AnalyticsBatchPayload.sessionIdremains as a deprecated optional type until 2.0 - Custom events (since 1.5.0; before that
trackEventonly logged to the console and sent nothing): buffered with the page views, tagged with the current path, and sent in the same batches, including thesendBeaconflush on hide/unload, whose next beacon resends first the events of any request still pending (same ids, stored once). See Custom events - A batch the server rejects with a 4xx other than 429 (bad key, disallowed origin, invalid payload) is dropped rather than retried forever; network errors, 429 and 5xx keep it queued for the next flush
- No screen-size analytics: versions up to 1.4.2 also sent
screenWidth(window.innerWidth) with every page view; no analytics view read it, so it is no longer collected or stored (the endpoint still accepts and ignores it from older SDKs).AnalyticsBeacon.screenWidthremains as a deprecated optional type until 2.0
FiveXXNode
Extends FiveXX with Node.js-specific features.
Constructor Options:
exitOnFatalError?: boolean- Exit process after fatal errors (default: true). Queued custom events get up to 2 seconds to flush before the exit
Additional Methods:
enableAutoCapture()- Auto-captureuncaughtExceptionandunhandledRejectionwrapHandler(fn)- Wrap HTTP route handlers to automatically capture errors (recommended for Next.js, Express, Fastify)wrapAsync(fn, metadata?)- Wrap any async function to capture errorstrackEvent(name: string, metadata?: object)- Track a custom event from server code (since 1.5.0). Queued and POSTed within 5 seconds, or as soon as 50 are queued; noenableAnalytics()step. After a 429, 5xx or any network failure (a refused or reset connection, the 3-second timeout), the batch stays queued and resends back off:Retry-Afterwhen the server sends one (up to an hour), otherwise 5 seconds doubling to 5 minutes, jittered. The server derives the "visitor" from the server's own IP and user agent, so put any user identity you need in metadataflushEvents(): Promise<void>- Send every queued custom event now, even while backing off. Never rejects. Await it before the process exits (serverless handlers, shutdown hooks), or queued events are lost
Custom events
fivexx.trackEvent('voice_session_ended', { reason: 'timeout', seconds: 42 });nameloses control characters and surrounding whitespace and is cut to 100 characters; an empty name is ignored with a warningmetadatamust be a plain JSON object of at most 2,048 characters when serialized. It is snapshotted at call time; anything else (an array, a cycle, a BigInt, something larger) is dropped with a warning and the event is sent without it- Unpaired UTF-16 surrogates (half an emoji left by
slice()) in the name, the path or any metadata key or string are replaced with U+FFFD before sending; the server does the same - Events go to
POST /api/analyticswith the project API key, alongside page views (customEventsin the batch), so the project's domain whitelist, bot filtering and analytics rate limit apply to them too. The Node client sends the User-Agent5xx-sdk-node/<version>, which the server's bot filter lets through for batches with no page views (a batch that contains page views is bot-filtered whatever its User-Agent), and no Origin header (accepted on the API key alone, like any server-side request) - Read them back with
GET /api/analytics/events?projectId=…&period=7d(counts per event name per UTC day;breakdown=reasonadds per-value counts of thereasonmetadata key, the only key broken down) or page the raw events withGET /api/export/events. Raw events are kept 30 days (except days skipped after repeated rollup failures); after that only the daily counts remain - Up to 500 events are queued while the server is unreachable; newer ones are dropped with a warning
- Each event gets a random
idwhentrackEventis called and keeps it on every retry and beacon; the server stores one event perid, so a batch resent after a lost response is not counted twice. Payloads without anid(hand-rolled callers) are stored at least once
Metadata
You can attach any metadata to errors:
fivexx.captureError(error, {
userId: 'user-123',
requestId: 'req-456',
action: 'checkout',
cart: { items: 3, total: 99.99 },
});The SDK automatically includes:
- User context (if set via
setUser()) - Browser: URL, user agent
- Node.js: Node version, platform, PID
Domain Whitelisting
If your 5xx project has allowed domains configured, the SDK sends an Origin header with each request. Requests from unlisted origins are rejected with 403. Server-side (Node.js) requests have no Origin header and rely on API key authentication only.
