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.What is protected by default
Without any configuration:- Every query parameter is removed from every URL AppSignal records.
?token=abcnever leaves the browser. - Request and response bodies are never recorded. There is no option to turn that on.
- No cookies are read or written. The SDK stores a few
appsignal_*values inlocalStorageandsessionStorage: random IDs for the session, the tab, and the visitor, the time of the last activity, and any tags you set. The visitor ID is a random value with nothing personal in it. It does stay on the device between visits, though, so treat it as an identifier and mention it in your privacy notice. - Console output is cut off after the first 200 characters.
- Nothing is sent when
activeisfalse. 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 worth keeping. Everything else is removed. 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 every URL AppSignal records: the URLs in network and navigation breadcrumbs, the page an error happened on, the page the user came from, and the page a web vital belongs to.
The last two rows are the important pair. Both URLs have something after a
#, and they are treated differently on purpose.
The third one looks like a query string after the #, so the same rules apply and the login token is removed. This is the case that matters: a token like that should never reach AppSignal. The fourth one looks like a route, which is how many single-page applications do their routing, so it is kept exactly as it is. A plain link to a section of a page, such as #pricing, is kept too.
Excluding network requests
privacy.networkBlocklist lists requests that should leave no breadcrumb. 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 take CSS selectors, and both apply to everything inside the element you name, so listing a container covers all of its contents.privacy.dom.maskText replaces the element’s text with [masked]. The breadcrumb is still recorded, so you keep the fact that someone selected it:
privacy.dom.blockElement records nothing at all. Use it for card forms, identity numbers, and anything that should never surface:
Filtering errors and breadcrumbs
Two functions let you inspect each error and each breadcrumb before AppSignal stores or sends anything. Neither can beasync.
beforeError runs once for every error. Return null to throw the error away, or change its fields to remove sensitive text from them. It is the one place to do both:
null gets rid of the error completely. No breadcrumb is recorded for it, and it does not count towards the rate limits.
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.
Tracking consent
Nothing is collected untilinit() 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
Here is what AppSignal for Browser records about a visit:- The pages they opened, and how far down each one they scrolled.
- What they selected, and where on the screen they selected it. Elements are recorded by their label, not their contents, unless the label happens to be the contents.
- The requests the page made, and whether each one succeeded.
- Warnings and errors the page logged to the console.
- Timing measurements.
- On errors, whatever tags you set.
setTags() or addBreadcrumb().