"use client"; import Script from "next/script"; import { ANALYTICS_PROXY_PATH, redactPayload, type UmamiPayload } from "@/lib/analytics"; /** Name of the global the tracker's `data-before-send` hook resolves. */ const BEFORE_SEND = "__umamiBeforeSend"; declare global { interface Window { [BEFORE_SEND]?: (type: string, payload: UmamiPayload) => UmamiPayload; } } // Registered at module scope rather than in an effect: the tracker reads // `window[BEFORE_SEND]` at send time, and this client chunk is evaluated before // next/script injects the tag, so there is no window in which an unredacted // event could slip out. if (typeof window !== "undefined") { window[BEFORE_SEND] = (_type, payload) => redactPayload(payload); } /** * Self-hosted Umami analytics. * * The tracker and its beacon are both served from this origin via the * `/_a` rewrite in next.config.mjs. That matters for more than ad-blockers: the * CSP in middleware.ts uses `'strict-dynamic'`, which makes browsers ignore host * allowlists in `script-src` entirely — so allowlisting the Umami domain there * would not have worked, and `connect-src 'self'` would still have blocked the * beacon. Proxying keeps both same-origin and the policy unrelaxed. */ export function UmamiAnalytics({ websiteId }: { websiteId: string }) { return (