Error tracking

Catch errors from your visitors' browsers and from your server, grouped by cause, with scrubbed messages and source-mapped stack traces.

Catch uncaught exceptions and unhandled promise rejections from real visitors, grouped by cause. Messages and stack traces are scrubbed of emails, tokens and long numbers on our servers before storage. The module dedups within each page load and caps sends so an error loop can't flood anything. Error tracking is completely free and never counts toward your quota.

index.html
<script defer
  data-website-id="YOUR_WEBSITE_ID"
  src="https://jamp.io/index.js">
</script>

Already handling an error in a try/catch? Report it yourself so it still shows up, flagged as handled:

app.js
try {
  riskyThing()
} catch (err) {
  window.jampError.capture(err)
}

Errors land under Monitor → Errors, grouped by a stable fingerprint so a thousand copies of the same crash collapse into one row.

Session trail

Each error carries a short trail of what the visitor was doing just before it fired: page navigations, clicks, and console errors. It is recorded in a small rolling buffer in the browser and only sent when an error happens, so it costs nothing on healthy pageviews. Clicks record the element and its label (a button's text, an aria-label), never what anyone typed, and labels are scrubbed of emails, tokens and long numbers on our servers like the rest of the error. Open any error to see the trail leading up to it.

Server-side errors

Catch exceptions thrown on your server too (route handlers, server components, middleware) using Next.js's onRequestError hook. Add this to your instrumentation.ts, with your site id and source-map key (both in Settings):

instrumentation.ts
export async function onRequestError(err, request) {
  await fetch('https://jamp.io/api/errors/server', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({
      website_id: 'YOUR_SITE_ID',
      key: 'YOUR_SOURCE_MAP_KEY',
      message: err?.message ?? String(err),
      stack: err?.stack,
      error_type: err?.name,
      route: request?.path,
      method: request?.method,
    }),
  })
}

Server errors show alongside client ones, tagged Server, grouped by route and message (for example POST /api/checkout).

Getting the full trace, not “Script error.”

Browsers hide the message and stack of errors thrown by a script served from a different origin (a CDN, for example), reporting only an opaque Script error. with no detail. To get the real trace, add crossorigin="anonymous" to your own script tags and serve those bundles with an Access-Control-Allow-Origin header. JAMP's own scripts already send CORS, and we drop these opaque cross-origin errors so they never clutter your dashboard.