"use client";
import { useReportWebVitals } from "next/web-vitals";
const KNOWN = new Set(["CLS", "FCP", "INP", "LCP", "TTFB"]);
/**
* Relays Core Web Vitals to jac-serve, which re-emits them as the
* `web_vitals` event shape the s10 console's Performance page groups by
* page (`context.pathname`). Uses Next's built-in reporting hook rather
* than a new dependency — it already wraps the standard `web-vitals`
* library. Best-effort: a failed beacon is dropped, never retried or
* surfaced, matching the shipper's own silent-on-failure invariant.
*/
export function WebVitalsReporter() {
useReportWebVitals((metric) => {
if (!KNOWN.has(metric.name)) return;
const body = JSON.stringify({
name: metric.name,
value: metric.value,
pathname: window.location.pathname,
});
const sent =
"sendBeacon" in navigator &&
navigator.sendBeacon("/api/telemetry/web-vitals", new Blob([body], { type: "application/json" }));
if (!sent) {
fetch("/api/telemetry/web-vitals", {
method: "POST",
headers: { "content-type": "application/json" },
body,
keepalive: true,
}).catch(() => {
// best-effort — a dropped metric is not worth surfacing
});
}
});
return null;
}