[invisit](https://invisit.dev) · [Docs](https://invisit.dev/docs) · [llms.txt](https://invisit.dev/llms.txt) · [llms-full.txt](https://invisit.dev/llms-full.txt)

# Errors

> JavaScript errors your visitors hit, grouped, with the stack, the pages and browsers involved, and how those visits did against the rest.

Source: https://invisit.dev/docs/guides/errors

**Errors** shows the JavaScript errors your visitors hit, grouped so one bug counts once, the ones reaching the most visits first. It is off until you turn it on in your code, it has [its own allowance](https://invisit.dev/docs/guides/billing.md#error-reports) that never touches your events, and it sits next to your traffic: every error links to the visit it happened in.

It is not a full error monitor. There are no source maps, assignments or release tracking. It tells you what broke, where, and for how many people.

## Turn it on

Set it where the tracker starts. Each site opts in from its own code, so it takes effect with your next deploy.

```ts
import { init } from '@invisitdev/web'

init({ site: 'YOUR_SITE_ID', errors: true })
```

```html
<script
  async
  src="https://api.invisit.dev/invisit.js"
  data-site="YOUR_SITE_ID"
  data-errors="true"
></script>
```

The listeners add about 250 bytes to the script. The rest, about 2 KB gzipped, loads only when a page has its first error, so a page without errors never downloads it.

## Errors your code catches

The browser only hears about errors nothing caught. An error boundary catches its errors first, so React, Vue and Next.js apps should report them:

```tsx
import { captureError } from '@invisitdev/web'

class Boundary extends React.Component {
  componentDidCatch(error) {
    captureError(error)
  }
}
```

With the script tag, call `invisit.captureError(error)`. It does nothing unless errors are turned on. In Vue, call it from `app.config.errorHandler`, and in Next.js from `error.tsx`.

## What is recorded

Uncaught errors, unhandled promise rejections, errors you capture, and your own scripts and stylesheets failing to load. A script that fails before the tracker has started goes unseen, since `async` scripts start late.

Noise is left out: errors from browser extensions, cancelled requests, `ResizeObserver` warnings, view transitions skipped because the tab was hidden, requests from an offline device, scripts cut off because the visitor left the page, and other sites' scripts failing to load, which is usually an ad blocker at work.

An error that repeats on a page is sent once, then once more with its total when the visitor leaves, so a loop can't flood your data. Reports never open or extend a visit, never count as events, and keep arriving while events are paused. Your plan sets [how many reports a month and a day](https://invisit.dev/docs/guides/billing.md#error-reports) you can store, and each site can start 1,000 new groups a day. Past the daily line a site's new reports are dropped until the next UTC day; past the monthly one they stop until the month turns, and your analytics are not affected.

## Your code and third parties

**Your code** is what ran from your page's domain or an [allowed domain](https://invisit.dev/docs/guides/privacy.md). **Third party** is everything else, such as a chat widget. If your bundles live on another domain, add it to your allowed domains or they will show as third party. The totals and the chart count both; the two tabs only switch the list below them.

`Script error` means a script on another origin failed and the browser hid why. Add `crossorigin="anonymous"` to that script tag, and have its server send `Access-Control-Allow-Origin`, to see the real error.

## Reading an error

Errors with the same type, message and file are one group. Numbers in the message and build hashes in the file name are ignored, so a deploy doesn't start a new group.

Opening one shows the newest stack, how often it happened, its pages, browsers, systems and countries, and the latest visits it reached, each of which opens step by step. With enough visits it also shows how visits with the error bounced and paid against those without it. That is a comparison, not proof the error caused the gap.

Stacks show your deployed files, so names can be minified. The line and column point into that build: build the same commit with source maps to find the original line.

## Privacy

Error text can hold data your program put there. Before anything leaves the page, and again when it arrives, email addresses, tokens, long numbers and quoted values are removed from messages, and query strings from every address. Only an Error's name, message and stack are read: a thrown object is never serialized. Consent, Global Privacy Control, Do Not Track and [excluded paths](https://invisit.dev/docs/guides/privacy.md) apply as they do to everything else. Errors never appear on public dashboards.

Error reports are kept like the rest of your analytics.

## Alerts and agents

**Error spike** in Settings → Alerts rings when at least 20 visits in an hour hit an error in your code, and at least three times the usual number.

The [MCP server](https://invisit.dev/docs/api/mcp.md)'s `get_errors` gives an agent the same data. With your code open, an agent can go from a group to its stack, to the visits it hit, and on to a fix.
