# Frontend Observability > Capture errors, measure real-user performance, and trace what breaks in production. Frontend architecture guidance from fearchitect, written by Abas Turabli and last reviewed 2026-06-21. Source: https://fearchitect.com/topics/frontend-observability Use it as reference for the task at hand. Before changing code, check this guidance against the codebase: where the code already makes a different, deliberate choice, flag the conflict instead of rewriting it. Library APIs move faster than this guide, so confirm exact signatures in the official docs linked at the end. ## Summary Frontend observability spans three layers: JavaScript error capture (window.onerror, unhandledrejection, framework error boundaries), real-user monitoring of Core Web Vitals via the web-vitals library, and network/API error tracking. Tools like Sentry add distributed tracing and session replay. Source maps tie minified stack traces back to source code. ## Frontend observability The practice of collecting errors, performance metrics, and behavioral traces from real browsers so you can diagnose production failures without reproducing them locally. It splits into three complementary layers: unhandled JS errors, framework-level error boundaries, and network/API failures. Each catches a different failure class; all three together give full coverage. ## Three error-capture layers - window.onerror + window.onunhandledrejection — catches synchronous throws and unhandled promise rejections that escape all other handlers. - Framework error boundaries (React ErrorBoundary, Vue errorHandler, Angular ErrorHandler) — catch render-phase exceptions and let you show a fallback UI. - Network/API errors — fetch wrappers or interceptors that track 4xx/5xx responses, timeouts, and offline failures that produce no JS exception. ## Sentry init + web-vitals RUM in one module Initialize Sentry once at app entry before any other imports, then wire web-vitals callbacks to send INP, LCP, and CLS to the same analytics endpoint. Both run in the browser only. **observability.ts — Sentry + web-vitals setup** ```ts import * as Sentry from "@sentry/browser"; import { onINP, onLCP, onCLS } from "web-vitals"; import type { Metric } from "web-vitals"; // --- Error tracking & tracing --- Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, // Attach traces to 20 % of sessions to stay within quota. tracesSampleRate: 0.2, // Session replay: 10 % of sessions, 100 % of sessions with an error. replaysSessionSampleRate: 0.1, replaysOnErrorSampleRate: 1.0, integrations: [ Sentry.replayIntegration({ // Block any element whose selector or text matches these patterns. blockAllMedia: true, maskAllText: true, // redacts all text nodes by default }), ], }); // --- Real-user monitoring --- function sendVital(metric: Metric): void { // navigator.sendBeacon queues the POST even if the page is unloading. navigator.sendBeacon( "/api/vitals", JSON.stringify({ name: metric.name, // "INP" | "LCP" | "CLS" value: metric.value, // ms for INP/LCP; unitless score for CLS rating: metric.rating, // "good" | "needs-improvement" | "poor" id: metric.id, }), ); } onINP(sendVital, { reportAllChanges: true }); onLCP(sendVital); onCLS(sendVital, { reportAllChanges: true }); ``` maskAllText: true in replayIntegration redacts every text node before upload — default-safe for PII. Raise replaysOnErrorSampleRate to 1.0 only; keep session rate low to control storage cost. ## Watch out: Session replay and PII Session replay records DOM snapshots. Without masking, it captures passwords, payment fields, and personal data. Sentry's maskAllText: true and blockAllMedia: true are safe defaults — opt individual elements out with data-sentry-unmask, not in. Verify your replay vendor's data-processing agreement covers your GDPR / CCPA obligations before enabling in production. ## Trade-offs of a full observability stack **Pros** - Source maps turn minified line numbers into actionable file + line references for every error. - Session replay cuts mean-time-to-reproduce from hours to minutes for hard-to-repro bugs. - RUM with web-vitals gives real-device INP/LCP data that Lighthouse cannot replicate. - Distributed tracing links a frontend error to the exact backend span, skipping log trawling. **Cons** - Sentry SDK adds ~50 kB gzipped; replay integration adds another ~20 kB. - Source maps uploaded to a public CDN expose your original code — upload only to Sentry, not the CDN. - High replay sample rates can breach storage quotas and slow the SDK's background thread. - window.onerror misses cross-origin script errors unless the server sets Access-Control-Allow-Origin and the script tag has crossorigin. ## Key terms - **window.onerror**: Global browser handler for uncaught synchronous JS errors; receives message, source, line, col, and the Error object. - **unhandledrejection**: Window event fired when a Promise rejects with no .catch() handler attached before the microtask checkpoint. - **Error boundary**: React class component (or its equivalent in other frameworks) that catches render-phase exceptions and renders a fallback subtree. - **RUM**: Real-User Monitoring — collecting performance metrics (LCP, INP, CLS) and error data from actual user browsers in production. - **Source map**: A .map file that maps minified/transpiled output back to original source file, line, and column for readable stack traces. ## Related topics - [Error Boundaries & Resilience](https://fearchitect.com/topics/error-boundaries-resilience.md): Isolate render failures so one widget can't crash the page. - [Core Web Vitals](https://fearchitect.com/topics/core-web-vitals.md): Google's three user-experience metrics: LCP, INP, and CLS. - [Frontend Testing Strategy](https://fearchitect.com/topics/frontend-testing.md): Test what the user sees, not how the code is wired. - [Network Performance](https://fearchitect.com/topics/network-performance.md): Hint, prioritize, and pre-navigate to cut request latency. - [A/B Testing & Experimentation](https://fearchitect.com/topics/ab-testing-experimentation.md): Ship variants without flicker using server-side bucketing and guardrail metrics. - [Accessibility (a11y)](https://fearchitect.com/topics/accessibility.md): WCAG 2.2 AA: semantic HTML, keyboard nav, and ARIA done right. ## Further reading - [Sentry — Browser JavaScript SDK setup](https://docs.sentry.io/platforms/javascript/) - [Sentry — Session Replay](https://docs.sentry.io/platforms/javascript/session-replay/) - [web-vitals — npm library by Google](https://github.com/GoogleChrome/web-vitals) - [MDN — Window: error event](https://developer.mozilla.org/en-US/docs/Web/API/Window/error_event) - [MDN — Window: unhandledrejection event](https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event)