import * as Sentry from '@sentry/vue'; import { defineNuxtPlugin, useRouter, useRuntimeConfig } from 'nuxt/app'; export default defineNuxtPlugin((nuxtApp) => { const router = useRouter(); const { public: { env, sentry } } = useRuntimeConfig(); if (!sentry.dsn) { return; } if (import.meta.env?.APP_ENV !== 'development') { // remove original error handler as this causes full-screen error pages nuxtApp.vueApp.config.errorHandler = undefined; } Sentry.init({ app: nuxtApp.vueApp, dsn: sentry.dsn, environment: env, integrations: [ Sentry.browserTracingIntegration({ router, enableInp: true }), ], tracesSampleRate: 0.1, attachStacktrace: true, tunnel: '/api/sentry/tunnel', beforeSend(event) { const denyUrls = [ 'chrome-extension://', 'moz-extension://', 'webkit-masked-url://', 'https://s0.2mdn.net', 'https://j.adlooxtracking.com', 'https://c.amazon-adsystem.com', 'https://assets.a-mo.net', 'https://btloader.com', 'https://challenges.cloudflare.com', 'https://static.criteo.net', 'https://securepubads.g.doubleclick.net', 'https://cdn.flashtalking.com', 'https://ajs-assets.ftstatic.com', 'https://cdn.fuseplatform.net', 'https://cmp.inmobi.com', 'https://cdn.js7k.com', 'https://z.moatads.com', 'https://ced-ns.sascdn.com', 'https://a.teads.tv', 'https://s.yimg.com', ]; // filter out exceptions originating from third party for (const exception of event.exception?.values || []) { for (const frame of exception.stacktrace?.frames || []) { const originatingFromThirdParty = denyUrls.some((denyUrl) => { return frame.abs_path?.startsWith(denyUrl) || frame.filename?.startsWith(denyUrl); }); if (originatingFromThirdParty) { return null; } } } // do not send user information as Sentry somehow automatically detects username, email and user id // https://docs.sentry.io/platforms/javascript/data-management/sensitive-data/ delete event.user; return event; }, beforeSendTransaction(event) { // see comment on beforeSend delete event.user; return event; }, }); });