npm.io
0.1.0 • Published 2d ago

@middle-monitor/web

Licence
MIT
Version
0.1.0
Deps
10
Size
20 kB
Vulns
1
Weekly
0

Middle-Monitor Web SDK

Web SDK for Middle-Monitor: error reporting and fetch/XHR tracing for any frontend framework.

Documentation: middlemonitor.io/docs#sdk-web

Framework-agnostic by design. The core hooks into the browser itself, so React, Vue, Angular, Svelte or plain JS all use the same three lines. Frameworks only differ in where they swallow errors, which is one extra line each (see Framework integration).

For a Node backend (Express, etc.), use @middle-monitor/sdk instead. This package will not run on the server.

Installation

npm install @middle-monitor/web

Usage

import { init } from '@middle-monitor/web';

init({
  apiUrl: 'https://api.middlemonitor.io',
  service: 'shop-web',
  token: import.meta.env.VITE_MIDDLE_MONITOR_TOKEN,
});

That is the whole setup. From there the SDK reports uncaught errors and unhandled promise rejections to the Errors view, and traces fetch / XMLHttpRequest calls.

Call it once, as early as possible — before your app mounts, so a crash during the first render is still caught.

Which token

Use a service token (Services > your service > token in the dashboard). A browser bundle is public: whatever token you put here is readable by every visitor, so it must be one that can only ingest.

Never use an mm_ org API key. Those authenticate on the dashboard API and would give any visitor read and write access to your whole organization.

Linking frontend traces to your backend

By default the SDK only adds the W3C traceparent header to same-origin requests. A cross-origin request carrying an unexpected header fails the target's CORS preflight, so it would break your API calls rather than trace them.

If your API is on another origin, list it — and allow the header on your side:

init({
  apiUrl: 'https://api.middlemonitor.io',
  service: 'shop-web',
  token: import.meta.env.VITE_MIDDLE_MONITOR_TOKEN,
  propagateTraceHeaderCorsUrls: [/^https:\/\/api\.myshop\.com/],
});

Your API must answer with Access-Control-Allow-Headers: traceparent. Once it does, a browser span and the server span it triggered belong to the same trace: a failed request in the UI leads straight to the handler that failed.

Reporting an error yourself
import { captureError } from '@middle-monitor/web';

try {
  await checkout(cart);
} catch (err) {
  captureError(err);
  showFallbackUI();
}

Framework integration

Every framework catches render errors before they reach window, so the global handler never sees them. Wire captureError into the framework's own hook to close that gap.

React
import { Component, ReactNode } from 'react';
import { captureError } from '@middle-monitor/web';

class ErrorBoundary extends Component<{ children: ReactNode }> {
  componentDidCatch(error: Error, info: { componentStack: string }) {
    captureError(error, { file: info.componentStack.trim().split('\n')[0] });
  }
  render() {
    return this.props.children;
  }
}
Vue
import { captureError } from '@middle-monitor/web';

app.config.errorHandler = (err, instance, info) => {
  captureError(err, { file: info });
};
Angular
import { ErrorHandler, Injectable } from '@angular/core';
import { captureError } from '@middle-monitor/web';

@Injectable()
export class MiddleMonitorErrorHandler implements ErrorHandler {
  handleError(error: unknown) {
    captureError(error);
  }
}

// providers: [{ provide: ErrorHandler, useClass: MiddleMonitorErrorHandler }]
Svelte
import { captureError } from '@middle-monitor/web';

// src/hooks.client.ts (SvelteKit)
export function handleError({ error }) {
  captureError(error);
}

Options

Option Default Description
apiUrl https://api.middlemonitor.io Middle-Monitor ingest URL.
service required Service name shown in the dashboard.
token none Service token. Reports land in the wrong place without it.
tracesSampleRate 0.1 Share of fetch/XHR traces to keep, 0 to 1. -1 selects the default. Errors are never sampled out.
propagateTraceHeaderCorsUrls [] Cross-origin URLs allowed to receive traceparent.
ignoreUrls [] URLs to never trace. The Middle-Monitor endpoint is always ignored.
captureGlobalErrors true Install window error and rejection handlers.
timeout 5000 Export timeout in milliseconds.

Sampling

tracesSampleRate applies to fetch/XHR spans only. Reported errors always reach the Errors view, whatever the rate: a dropped crash report is a crash nobody sees.

Unlike the server SDKs, the browser cannot keep a trace because it failed. The sampling decision is made when a request starts, and the status only exists once it ends. Set the rate to 1 on a low-traffic frontend if you want every request.

API

  • init(options) — start the SDK. Idempotent: a second call is ignored, so HMR does not double-report.
  • captureError(error, location?) — report an error. Accepts anything throwable, not just Error.
  • flush() — export pending spans now.
  • shutdown() — detach handlers and stop exporting.

Keywords