Grafana Cloud

Faro Web-SDK FAQ

How does Faro collect errors?

We register two error handlers:

  • onError: to catch unhandled exceptions. The Faro data model for errors is a structured format containing the line number of the script file where the error occurred.
  • onunhandledrejection to catch errors from rejected JavaScript Promises which don not have rejection handlers attached.

Why am I seeing script error instead of a full stacktrace?

When errors happen in third-party scripts, we can not get the stack trace information because browsers restrict access for security reasons. Browsers will replace the contents of errors with a generic “Script Error.” message.

If your trust the resources, you can instruct browsers to reveal the error messages of third-party scripts.

  1. Add crossorigin="anonymous" to the respective script tags. This will instruct the browser to set mode to cors and the credentials mode to same-origin for that specific request.
  2. The HTTP response which delivers the script to the client needs to have the Access-Control-Allow-Origin header set.

HTML File:

<!-- -->
<script src="" crossorigin="anonymous"></script>



Does Faro allow to modify beacon data before sending it?

Faro provides the beforeSend hook which gets the current beacon (TransportItem) as it’s parameter.

  // ... faro configuration
  beforeSend: (item) => {
    switch (item.type) {
      case 'exception':
      case 'event':
      case 'trace':
      case 'measurement':
        return item;
      case 'log':
        return item.meta.user?.attributes?.['sendNoLogs'] ? null : item;

Does Faro deduplicate Events?

To reduce data usage Faro deduplicates events. Means if two similar events are emitted consecutively, Faro only sends the event once.

How can I Instrument composable frontends?

You can use independent Faro instances per frontend. Simply initialize a Faro instance per microfrontend you want to instrument by setting the isolate property to true. This tells the local Faro instance to not use the global instance APIs.

Initialize a global Faro instance to capture everything which you want to capture for the global scope. Additionally you initialize a Faro instance per sub-frontend (with isolate=true) to capture only the desired events for the local scope. To reduce the bundle size you may want to only add the instrumentations you need and let the global instance capture everything else.

To filter sources which shall not be captured by the global app you may want to use the onBeforeSend() hook on the global instance. For example if you also want to capture errors on the sub-frontend level. Then on the global instance you can filter out those events which are related to the specific sub-fronted only.


  beforeSend: (item) => {
    const isException = item.type === 'exception'

    if (isException && !( ?? '').includes('foo')) {
      return null;

    return event;

Does Faro store or use any cookies?

No Faro does not store or use any cookies.

Faro stores session information in the browsers web-storage which has the following structure.

export interface FaroUserSession {
  sessionId: string; // randomly created sessionID
  lastActivity: number; // last user/browser activity
  started: number; // when the session has been started
  isSampled: boolean; // is the session part of the sample
  sessionMeta?: MetaSession; // a copy of the in-memory session meta object

Depending on the chosen session mechanism Faro stores this data in the browsers:

  • Session Storage, if volatile sessions is enabled (default)

    • The data is removed when the browser tab or browser window is closed.
  • Local Storage, if persistent sessions is enabled

    • The data has no max lifetime but will be removed if maxSessionPersistenceTime is reached for a recurring visitor.

      Default value is 16 minutes, can be configured by the user.


      Attributes added to a user session manually may be stored in the sessionMeta as well, so PII
      data should never be added to the session meta.