@accelerup-llc/web-monitor
v0.5.1
Published
Lightweight, zero-dependency error & warning monitoring SDK for Next.js (App Router + Pages Router). Init once, capture everything.
Downloads
481
Maintainers
Readme
@accelerup-llc/web-monitor
Lightweight, zero-dependency error & warning monitoring for Next.js. Initialize
once, and every uncaught error, unhandled promise rejection, console.error
and console.warn from your users is batched and shipped to AccelerUp. Works
with both the App Router and the Pages Router in the same codebase.
- Zero runtime dependencies — a few KB gzipped,
reactis an optional peer. - Errors & warnings only — nothing else is captured. No
console.log, no analytics, no tracking. - Single init, idempotent — safe across HMR, double imports, and both routers mounting.
- Never breaks your app — every capture path is wrapped; failures are swallowed.
- Resilient transport — batched, deduped, rate-limited,
sendBeaconon page hide, retry with backoff.
Install
npm install @accelerup-llc/web-monitorSetup — one place, both routers
1. Add two env vars (.env):
NEXT_PUBLIC_ACCELERUP_INGEST_URL=https://api.accelerup.com/ingest/web-errors
NEXT_PUBLIC_ACCELERUP_KEY=wm_your_public_ingest_keyThe key is public and write-only — it only grants "submit an error event", so it is safe to expose in the browser bundle.
2. Init once. Next.js 13.4+ runs instrumentation-client.ts (project root,
or src/) on the client before anything else, for both routers — the single
init point:
// instrumentation-client.ts
import { init } from '@accelerup-llc/web-monitor';
init({
ingestUrl: process.env.NEXT_PUBLIC_ACCELERUP_INGEST_URL!,
key: process.env.NEXT_PUBLIC_ACCELERUP_KEY!,
release: process.env.NEXT_PUBLIC_APP_VERSION,
environment: process.env.NODE_ENV,
});That's it. No other code changes anywhere in your app.
Prefer a single DSN string?
init({ dsn: 'https://KEY@host/PROJECT_ID' })also works.
App Router — a tiny client component imported in the root layout:
// app/monitor.tsx
'use client';
import { useEffect } from 'react';
import { init } from '@accelerup-llc/web-monitor';
export function Monitor() {
useEffect(() => { init({ dsn: process.env.NEXT_PUBLIC_ACCELERUP_DSN! }); }, []);
return null;
}// app/layout.tsx
import { Monitor } from './monitor';
export default function RootLayout({ children }) {
return <html><body><Monitor />{children}</body></html>;
}Pages Router — in _app.tsx:
// pages/_app.tsx
import { init } from '@accelerup-llc/web-monitor';
if (typeof window !== 'undefined') init({ dsn: process.env.NEXT_PUBLIC_ACCELERUP_DSN! });Optional: React error boundary
Catches render-time crashes that global handlers can't see.
import { ErrorBoundary } from '@accelerup-llc/web-monitor/react';
<ErrorBoundary fallback={<p>Something went wrong.</p>}>
<YourApp />
</ErrorBoundary>Optional: manual reporting
import { captureError, captureMessage, setUser } from '@accelerup-llc/web-monitor';
try { risky(); } catch (e) { captureError(e); }
captureMessage('Payment retried', 'warning');
setUser({ id: 'user_123' }); // anonymous id only — no PII requiredConfiguration
| Option | Default | Description |
| --- | --- | --- |
| ingestUrl + key | — | Required (or dsn). Endpoint URL + public ingest key. |
| project | — | Optional app id, sent as a tag. |
| dsn | — | Alternative to ingestUrl+key: https://KEY@host/PROJECT_ID. |
| endpoint | derived | Override the full ingest URL (with dsn). |
| release / environment | — | Group issues per release/env. |
| enabled | true | Set false to disable entirely. |
| captureError | true | Uncaught window errors. |
| captureUnhandledRejection | true | Unhandled promise rejections. |
| captureConsole | true | console.error/warn. Or { error, warn }. |
| ignoreErrors | — | (string \| RegExp)[] to drop by message. |
| denyUrls / allowUrls | — | Filter by stack/url. |
| sampleRate / warningSampleRate | 1 | 0..1 sampling. |
| maxEventsPerMinute | 30 | Token-bucket flood guard. |
| dedupeWindow | 5000 | ms window to suppress duplicates. |
| flushInterval / maxBatchSize | 5000 / 20 | Batching. |
| maxQueueSize | 100 | In-memory buffer cap. |
| beforeSend | — | (event) => event \| null last-chance hook. |
| posthog | true | Pivot errors to PostHog session replay (see below). |
| debug | false | Verbose internal logging. |
PostHog integration
If you already use PostHog (cloud or self-hosted), the SDK auto-pivots from an error to the same session's replay video — no extra config, no custom breadcrumbs to rebuild.
When window.posthog is loaded on the page, every event is tagged with:
posthog_distinct_id— current user idposthog_session_id— current session idposthog_session_url— direct link into PostHog session replay, anchored at the moment of the error (built by PostHog's ownget_session_replay_url, so self-hosted instances "just work" with their configuredapi_host)
In the AccelerUp dashboard, error detail pages render an Open in PostHog
session replay button when these tags are present. Set posthog: false
to disable.
Privacy
URLs are reduced to origin + pathname (query & hash stripped) to avoid leaking
tokens/PII. Only error/warning content is collected. Use beforeSend to redact
further.
License
MIT
