// Grafana Faro — browser RUM SDK initializer. // Sends Web Vitals, JS errors, console messages, fetch/XHR, navigation, // and React component lifecycle events to Grafana Alloy via OTLP HTTP. // // Required env vars (Vite injects VITE_* at build time): // VITE_FARO_ENDPOINT — e.g. http://localhost:4318 // VITE_FARO_APP_NAME — e.g. farmaclic-frontend // VITE_FARO_ENV — e.g. production | staging | development // VITE_FARO_APP_VERSION — optional, defaults to 1.0.0 import { getWebInstrumentations, ReactIntegration, initializeFaro, } from '@grafana/faro-react'; import { TracingInstrumentation } from '@grafana/faro-web-tracing'; import { OtlpHttpTransport } from '@grafana/faro-transport-otlp-http'; let initialized = false; let faroApi = null; export function getFaro() { return faroApi; } export function initFaro() { if (initialized) return; initialized = true; const endpoint = import.meta.env.VITE_FARO_ENDPOINT; if (!endpoint) { // Faro is optional. If the endpoint is not configured (e.g. local dev // without an Alloy collector), do nothing so the app still runs. return; } const appName = import.meta.env.VITE_FARO_APP_NAME || 'farmaclic-frontend'; const environment = import.meta.env.VITE_FARO_ENV || 'production'; const version = import.meta.env.VITE_FARO_APP_VERSION || '1.0.0'; try { const faro = initializeFaro({ url: `${endpoint.replace(/\/$/, '')}/v1/traces`, app: { name: appName, environment, version, }, instrumentations: [ ...getWebInstrumentations({ captureConsole: true, captureConsoleDisabledLevels: ['debug'], captureException: true, captureMessage: true, captureResource: true, captureUserInteraction: true, captureXHRInstrumentation: true, captureFetchInstrumentation: true, captureWebVitals: true, captureNavigation: true, }), new ReactIntegration(), new TracingInstrumentation(), ], transport: new OtlpHttpTransport({ url: `${endpoint.replace(/\/$/, '')}/v1/traces`, }), }); faroApi = faro.api; // Expose for ErrorBoundary and manual reporting window.__faro = faro; } catch (err) { // Never let Faro init failure break the app. // eslint-disable-next-line no-console console.warn('[faro] init failed', err); } }