Skip to main content
Browser monitoring is a beta AppSignal Labs feature. The @appsignal/browser package is published under the beta tag on npm, and its configuration and API may still change between beta releases. Share feedback in our Discord community.
Front-end telemetry sits closer to personal data than back-end telemetry does. URLs carry tokens, forms carry card numbers, and the text on a button can be an order total. AppSignal for Browser is conservative by default, and every remaining decision is yours to configure.

What is protected by default

Without any configuration:
  • Most SDK-created URL fields omit query parameters by default. This covers error page URLs, web-vital page URLs, navigation breadcrumbs, and fetch/XMLHttpRequest breadcrumbs. The initial document-load network breadcrumb is an exception, explained below.
  • The SDK does not read request or response bodies from network calls. Review data your own code puts in errors, console output, tags, or manual breadcrumbs.
  • No cookies are read or written. The SDK stores appsignal_* values in localStorage and sessionStorage. These include random session, tab, and visitor IDs, activity time, and tags you set. The visitor ID is a random value with nothing personal in it. The visitor ID persists between visits. Treat it as an identifier in your privacy notice.
  • Console warnings and errors are cut off after the first 200 characters. The SDK does not capture console.log.
  • Nothing is sent when active is false. The SDK does not change anything on the page, start any timers, or make any requests.

URLs and query parameters

privacy.queryParamsAllowlist lists the query parameters to keep in the URL fields below. Other query parameters are removed from those fields. You can use * to match several names at once, so utm_* keeps every UTM parameter. The default list is empty, which removes all of them. This applies to fetch/XMLHttpRequest and navigation breadcrumbs. It also applies to automatically reported request errors, error page URLs, referrers, and web-vital page URLs.
With that setting: The last two rows are the important pair. Both URLs have something after a #, and they are treated differently on purpose. The third URL has plain query-style data after #, so the SDK removes its token from these scrubbed fields. The fourth URL is a hash route, which the SDK preserves. That includes any query text inside a hash route, such as #/payment?token=abc. Keep secrets out of hash routes. Plain anchors such as #pricing are preserved too.
The initial document-load network breadcrumb currently uses the full landing URL, even when queryParamsAllowlist is empty. networkBlocklist does not filter it. If landing URLs may contain secrets, drop this breadcrumb with beforeBreadcrumb:

Excluding network requests

privacy.networkBlocklist lists fetch and XMLHttpRequest calls that should leave no breadcrumb, and that are never reported as failed requests either. The request still happens as normal. It is only the record of it that is skipped. Patterns are matched against the host and the path of the URL. A single * matches one part of the path, and ** matches any number of parts.

Masking and blocking page elements

Two options control what gets recorded when a user selects something. Both options take CSS selectors. Selecting a container also covers its descendants. privacy.dom.maskText replaces text from a matching element with [masked]. The breadcrumb is still recorded, so you keep the fact that someone selected it:
A data-breadcrumb label takes precedence over text masking. Do not put sensitive values in that attribute. privacy.dom.blockElement records nothing at all. Use it for card forms, identity numbers, and anything that should never surface:
These two options only affect what is recorded when a user selects something. They do not touch error messages, network URLs, or console warnings and errors. Use queryParamsAllowlist, networkBlocklist, and the two functions in the following section for those.

Filtering errors and breadcrumbs

Two hooks let you filter errors before reporting and breadcrumbs before they enter the buffer. Neither can be async. beforeError runs for errors that pass sampling and the global rate limit. Return null to drop an error, or change its fields to remove sensitive text:
Returning null sends no error and adds no error breadcrumb. The global rate limit is checked first, so dropped errors still count toward it. A failed request arrives here as an HTTPError or TimeoutError. Its url, method, status, and duration_ms are under context.request. If you redact the URL there, also redact it in the error message, which contains the request URL. beforeBreadcrumb runs once for every breadcrumb, as it is recorded. Return null to throw it away, or change its message and data:
beforeError cannot see breadcrumbs, because they are attached to the error after this function has approved it. Use beforeBreadcrumb to clean up breadcrumb content instead.
Neither function can be async. If beforeError returns a promise, AppSignal logs a console.error and throws the error away. Do any slow work before you call captureError, not inside these functions.
Nothing is collected until init() runs, so asking for consent first is a matter of not calling it until you have it:
destroy() stops collection straight away, sending whatever it had already gathered. It only affects the page the user is on. Store their decision yourself and check it before calling init(), or the next page they open starts collecting again.

What you can tell your users

A reported error can include up to 25 recent breadcrumbs. Depending on what happened before it, these may describe:
  • The pages they opened.
  • What they selected, and where on the screen they selected it. Click labels can include visible text, so mask sensitive elements.
  • The requests the page made, and whether each one succeeded.
  • Warnings and errors the page logged to the console.
  • Long tasks.
The error also includes any tags you set. Web-vital batches contain metric values and visit context, but do not include this breadcrumb trail by default. The breadcrumbs page has the full list. Every web-vitals batch also carries visit context. This includes random session, tab, and visitor IDs, the page URL, and its referrer. It also includes the user agent, screen and window sizes, language, and time zone. Where the browser makes them available, it also carries the connection type and how much memory the device has. The SDK does not directly read form field values, network bodies, or cookies. The SDK generates a random visitor ID. It persists on the device between visits. Your own error messages, tags, and breadcrumbs can contain personal details. Review them before sending data to AppSignal.