# Bug report context and screenshots

See which browser diagnostics, screenshots, recordings, and attachments Annot8 captures with feedback, and which data it excludes.

Source: https://docs.annot8.app/docs/widget/capture



The point of Annot8 is that the follow-up question ("what browser? what were you
doing? any errors?") is already answered before you ask it. Here's exactly
what's collected, and when.

## Always captured [#always-captured]

Attached to every thread at submit time, with no reviewer action:

<Accordions>
  <Accordion title="Anchor">
    The CSS selector for the element that was clicked, plus a percentage offset
    inside it. Storing the offset as a percentage is what lets the pin survive
    scrolling, window resizing, and most re-deploys.
  </Accordion>

  <Accordion title="Page context">
    URL path, full page URL, page title, and referrer. Feedback URLs are minimised —
    query strings and hash fragments are stripped before storage.
  </Accordion>

  <Accordion title="Device context">
    Viewport width and height, device type (desktop / tablet / mobile), user agent,
    scroll position, device pixel ratio, language, timezone, and whether the visitor
    is in light or dark mode.
  </Accordion>

  <Accordion title="Element context">
    Tag name, `id`, class list, truncated inner text, truncated outer HTML, and
    `href`, `src`, or `placeholder` where they apply. Enough for a developer to find
    the component in the codebase.
  </Accordion>

  <Accordion title="Diagnostics">
    * **Console errors** — the most recent 20 `console.error` calls, uncaught
      errors, and unhandled promise rejections from the session
    * **Network failures** — the most recent 20 failed or non-OK `fetch` and
      `XMLHttpRequest` calls, with method, URL, and status
    * **Performance timings** — DOM content loaded, load time, first paint, first
      contentful paint, largest contentful paint, time to interactive, and JS heap
      usage where the browser exposes it

    Capture starts when the widget initialises, so errors that fire before it loads
    aren't included.
  </Accordion>

  <Accordion title="Screenshot">
    A render of the page at the moment of annotation, produced client-side. Capped
    at 8 MB and abandoned after 12 seconds on a very large DOM — in which case the
    thread is still submitted, just without the image.
  </Accordion>
</Accordions>

## Optional attachments [#optional-attachments]

Each is a deliberate reviewer action, never automatic.

| Attachment                     | Notes                                                                                                                                                                           |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Screen recording** (**Pro**) | Browser-level capture via `getDisplayMedia`. Video only — Annot8 never requests microphone audio for a recording. The reviewer previews it and can discard it before submitting |
| **Voice note**                 | Microphone recording, up to 2 minutes, with echo cancellation and noise suppression                                                                                             |
| **Steps to reproduce**         | The clicks, scrolls, inputs, and navigations leading up to the report                                                                                                           |

Voice notes and screen recordings are transcribed automatically when
[AI](/docs/ai/overview) is available on your plan, so the text is searchable and
readable without playing the media.

## Redaction [#redaction]

Screenshots are generated by cloning the DOM, so Annot8 masks known-sensitive
regions before rendering. Masked by default:

* `input`, `textarea`, `select`
* content-editable regions
* `iframe` and `video`
* anything marked `[data-private]`

Add your own with `data-annot8-redact` (obscured, layout preserved) or
`data-annot8-ignore` (omitted entirely), or declare up to 25 selectors via
`window.annot8RedactSelectors`. Full details in
[Widget configuration](/docs/widget/configuration#keeping-sensitive-content-out-of-screenshots).

<Callout type="warn">
  Screen recording is a browser-level capture. It **cannot** be redacted
  automatically — no DOM masking applies to it. The reviewer is warned and must
  review the recording before submitting.
</Callout>

## What is never collected [#what-is-never-collected]

* **Your app's cookies and storage.** The storage snapshot is filtered to
  Annot8's own keys, and it records *key names* only. Your application's keys
  are skipped entirely, and no stored value is ever read or transmitted.
* **Keystrokes.** There is no keylogger and no session replay.
* **Microphone audio during a screen recording.** The recorder requests
  `audio: false`.
* **Query strings and hashes on feedback URLs.** Stripped before storage, since
  they routinely carry tokens and personal data.

[Analytics](/docs/analytics/overview) is a separate, consent-gated system with
its own collection rules — it is off by default and never runs unless you both
enable and consent to it.

## Go to location [#go-to-location]

Every thread in the dashboard has a **Go to location** action. It opens the
annotated page with the pin's position in the query string, and the widget on
that page resolves it.

Because the element may not exist on load — it might be inside a modal, an
accordion, a tab panel, or a route that hasn't rendered — the widget keeps
watching for it rather than giving up on the first miss, and tells you when the
element genuinely never appears (usually because something needs clicking
first).
