Multiple Sentry Instances

To be able to manage several Sentry instances without any conflicts between them you need to create your own Client. This also helps to prevent tracking of any parent application errors in case your application is integrated inside of it. In this example we use BrowserClient from @sentry/browser but it's also applicable to NodeClient from @sentry/node.

Copied
import {
  BrowserClient,
  defaultStackParser,
  defaultIntegrations,
  makeFetchTransport,
  Scope,
} from "@sentry/browser";

const client = new BrowserClient({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  transport: makeFetchTransport,
  stackParser: defaultStackParser,
  integrations: defaultIntegrations,
});

const scope = new Scope();
scope.setClient(client);

client.init() // initializing has to be done after setting the client on the scope

// You can capture exceptions manually for this client like this:
scope.captureException(new Error("example"));

You can now customize the scope to your liking, without affecting other hubs/clients.

Integrations are setup on the Client, if you need to deal with multiple clients and hubs you have to make sure to also do the integration handling correctly.

We do not recommend doing this if you are using Sentry in a browser extension or in similar scenarios. If you can't avoid using global integrations (e.g. in a micro frontend application), here is a working example of how to use multiple clients with multiple scopes running global integrations.

Copied
import * as Sentry from "@sentry/browser";

// Very happy integration that'll prepend and append very happy stick figure to the message
function happyIntegration() {
  return {
    name: 'Happy',
    setupOnce() {
      Sentry.addGlobalEventProcessor((event) => {
        const self = Sentry.getClient().getIntegration(HappyIntegration);
        // Run the integration ONLY when it was installed on the current Hub
        if (self) {
          event.message = `\\o/ ${event.message} \\o/`;
        }
        return event;
      });
    }
  }
}

const client1 = new Sentry.BrowserClient({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  transport: Sentry.makeFetchTransport,
  stackParser: Sentry.defaultStackParser,
  integrations: [...Sentry.defaultIntegrations, happyIntegration()],
  beforeSend(event) {
    console.log("client 1", event);
    return null; // Returning `null` prevents the event from being sent
  },
});
const scope1 = new Sentry.Scope(client1);

const client2 = new Sentry.BrowserClient({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", // Can be a different DSN
  transport: Sentry.makeFetchTransport,
  stackParser: Sentry.defaultStackParser,
  integrations: [...Sentry.defaultIntegrations, happyIntegration()],
  beforeSend(event) {
    console.log("client 2", event);
    return null; // Returning `null` prevents the event from being sent
  },
});
const scope2 = new Sentry.Scope(client2);

scope1.captureMessage("a");
scope1.setTag("a", "b");

scope2.captureMessage("x");
scope2.setTag("c", "d");
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").