npm package: 5xx-sdk
Description: Lightweight error tracking SDK for JavaScript/TypeScript applications
Latest version: 1.3.1

# @5xx/sdk

Lightweight error tracking and analytics SDK for JavaScript/TypeScript applications.

## Installation

```bash
npm install @5xx/sdk
```

Or copy the SDK files directly into your project.

## Quick Start

### Browser

```typescript
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: 'user@example.com',
});

// Manual error capture
try {
  riskyOperation();
} catch (error) {
  fivexx.captureError(error, { context: 'checkout' });
}

// Track custom events
fivexx.trackEvent('signup_completed', { plan: 'pro' });
```

### Node.js

```typescript
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',
});
```

### Universal (works in both environments)

```typescript
import { FiveXX } from '@5xx/sdk';

const fivexx = new FiveXX({
  apiKey: 'your-api-key',
  endpoint: 'https://your-5xx-instance.com',
  environment: 'production',
});

// Manual capture only
fivexx.captureError(new Error('Something went wrong'));
fivexx.captureMessage('User performed invalid action');
```

## API

### FiveXX (Base Client)

```typescript
new FiveXX(options: FiveXXOptions)

interface FiveXXOptions {
  apiKey: string;      // Your project's API key
  endpoint: string;    // Your 5xx instance URL
  environment?: string; // e.g., "production", "staging"
}
```

**Methods:**
- `setEnvironment(env: string)` - Set the environment
- `setUser(user: User | null)` - Set user context for errors
- `captureError(error: Error, metadata?: object)` - Capture an error
- `captureMessage(message: string, metadata?: object)` - Capture a message

### FiveXXBrowser

Extends FiveXX with browser-specific features.

**Additional Methods:**
- `enableAutoCapture()` - Auto-capture `window.onerror` and `unhandledrejection`
- `disableAutoCapture()` - Disable auto-capture
- `enableAnalytics()` - Enable page view tracking, SPA navigation, and visitor analytics
- `trackEvent(name: string, metadata?: object)` - Track a custom event

**Analytics behaviour:**
- Opt-in via `enableAnalytics()` — does not affect error tracking
- Automatically tracks page views on load
- SPA support: patches `pushState`/`replaceState` and listens for `popstate`
- Batches analytics beacons and sends every 5 seconds
- Uses `navigator.sendBeacon()` on page unload to prevent data loss
- Strips query params from URLs (keeps UTM params: `utm_source`, `utm_medium`, `utm_campaign`, and `ref`)
- Privacy-friendly: no cookies, no fingerprinting. Visitor ID is derived server-side from IP + user agent + daily rotating salt

### FiveXXNode

Extends FiveXX with Node.js-specific features.

**Constructor Options:**
- `exitOnFatalError?: boolean` - Exit process after fatal errors (default: true)

**Additional Methods:**
- `enableAutoCapture()` - Auto-capture `uncaughtException` and `unhandledRejection`
- `wrapHandler(fn)` - Wrap HTTP route handlers to automatically capture errors (recommended for Next.js, Express, Fastify)
- `wrapAsync(fn, metadata?)` - Wrap any async function to capture errors

## Metadata

You can attach any metadata to errors:

```typescript
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.