docs

User feedback

Let the people using your app tell you what went wrong, with the error and trace they hit attached. The browser SDK's feedback API and widget, where feedback shows up, and how it is kept.

User feedback is a note an end user of your app sends from the page they are on. The browser SDK sends it with your public DSN, and Unhandled attaches it to the last error the SDK reported on that page and to the trace it belonged to. You read it on the issue it is about and on the User Feedback page.

It is not the same as the feedback you send the Unhandled team from the help menu. That goes to us; this comes from your users to you.

Collect feedback

Nothing is collected until you add it. Either call the API from your own UI:

ts
const result = await unhandled.captureFeedback({ message: 'The total stayed at 0 after I added a coupon' })
if (!result.ok) showError(result.message)

or add the feedbackWidget() integration, which renders a small button and a dialog with a message field and optional name and email fields:

ts
import { errors, feedbackWidget, initUnhandled, network } from '@unhandled/browser'

initUnhandled({
  dsn: import.meta.env.VITE_UNHANDLED_DSN,
  environment: 'production',
  integrations: [network(), errors(), feedbackWidget()],
})

The browser SDK reference lists every option, the result codes and the widget's labels.

What is sent

FieldWhere it comes from
MessageWhat the person typed. Required, up to 5,000 characters, plain text only
Name, emailOnly what the person typed or your code passed. Never taken from setUser()
Occurrence and traceThe last error the SDK reported on the page and its trace, or the page load's trace when there was no error
Page URLSanitised like error reports: no query string or fragment, token-like path segments replaced
ReleaseThe service version the SDK resolved

Unhandled refuses a message that holds HTML (a < followed by a letter, /, ! or ?), control characters, or an email that is not an address, and tells the widget why.

Where it shows up

  • Issue page. The Feedback tab lists what users sent about that issue, newest first, with how many in the tab title. Feedback follows the issue's grouping keys, so it moves with the issue when you merge or unmerge.
  • User Feedback page. Everything in the selected environment, services and time range, with a text search over message, name and email, and a filter for feedback about an error or not linked to one. Each entry links to its issue and its trace.
  • MCP. list_feedback and get_feedback, and get_issue returns the count and the latest five. Feedback text is marked as untrusted in the result, like other text your users write.

Everyone who can view the project sees its feedback. Feedback is not sent to an AI provider: neither AI summaries nor fix prompts include it.

Linking to the error

The SDK sends queued telemetry before the feedback, so the error normally arrives first. Unhandled links the feedback to the error when it stores it, from errors that arrived up to an hour earlier. Feedback whose error was dropped (for example by an occurrence cap) or happened more than an hour before stays on the User Feedback page as not linked.

Limits

Feedback goes to the same receiver as the rest of your telemetry and passes the same key, origin and quota checks. On top of those, the receiver accepts 10 submissions a minute per service, and from one network (an IPv4 address or an IPv6 /56) a burst of 5, then 30 an hour per service. Past either, the SDK gets rate_limited with the wait in seconds. Unhandled then stores at most 1,000 submissions per project per UTC day and drops the rest; the count resets at midnight UTC.

Retention and deletion

Feedback is kept as long as your errors retention and deleted with its project or organization.