fix(csp): whitelist Umami analytics origin so tracking works
The CSP script-src/connect-src didn't include the Umami host (fickanalytics.phluit.net), so the browser blocked both loading script.js and the event beacons (POST /api/send) — analytics recorded 0 visits despite the site being live. Add a umamiOrigin() helper (derived from NEXT_PUBLIC_UMAMI_SRC, defaulting to the shared phluit instance) and include it in script-src and connect-src. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5a555c715e
commit
e5e987eb4c
@@ -41,6 +41,19 @@ function sentryIngestOrigin(): string | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Origin serving the Umami analytics script (script.js) and receiving its event
|
||||||
|
// beacons (POST /api/send). Mirrors the component default so the CSP allows both
|
||||||
|
// loading the script AND sending events; stays in sync with NEXT_PUBLIC_UMAMI_SRC
|
||||||
|
// when overridden.
|
||||||
|
function umamiOrigin(): string {
|
||||||
|
const src = process.env.NEXT_PUBLIC_UMAMI_SRC || "https://fickanalytics.phluit.net/script.js"
|
||||||
|
try {
|
||||||
|
return new URL(src).origin
|
||||||
|
} catch {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Build the Content-Security-Policy. `script-src` uses 'unsafe-inline' because
|
// Build the Content-Security-Policy. `script-src` uses 'unsafe-inline' because
|
||||||
// Next.js 16's Turbopack build does NOT stamp a per-request nonce onto its
|
// Next.js 16's Turbopack build does NOT stamp a per-request nonce onto its
|
||||||
// inline hydration scripts (`self.__next_f.push(...)`). A nonce-based policy
|
// inline hydration scripts (`self.__next_f.push(...)`). A nonce-based policy
|
||||||
@@ -54,13 +67,20 @@ function buildCsp(): string {
|
|||||||
|
|
||||||
// Dev additionally needs 'unsafe-eval' (Turbopack HMR) plus a dev websocket
|
// Dev additionally needs 'unsafe-eval' (Turbopack HMR) plus a dev websocket
|
||||||
// (added to connect-src below).
|
// (added to connect-src below).
|
||||||
const scriptSrc = isDev
|
const umami = umamiOrigin()
|
||||||
? `script-src 'self' 'unsafe-inline' 'unsafe-eval' https://challenges.cloudflare.com`
|
const scriptSrc = [
|
||||||
: `script-src 'self' 'unsafe-inline' https://challenges.cloudflare.com`
|
"script-src 'self' 'unsafe-inline'",
|
||||||
|
isDev ? "'unsafe-eval'" : "",
|
||||||
|
"https://challenges.cloudflare.com",
|
||||||
|
umami, // load the Umami analytics script
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" ")
|
||||||
const connectSrc = [
|
const connectSrc = [
|
||||||
"connect-src 'self'",
|
"connect-src 'self'",
|
||||||
isDev ? "ws: wss:" : "",
|
isDev ? "ws: wss:" : "",
|
||||||
"https://api.stripe.com https://api.openai.com https://challenges.cloudflare.com",
|
"https://api.stripe.com https://api.openai.com https://challenges.cloudflare.com",
|
||||||
|
umami, // Umami event beacons (POST /api/send)
|
||||||
sentry ?? "",
|
sentry ?? "",
|
||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
|
|||||||
Reference in New Issue
Block a user