chore(analytics): mover configuração do Umami para variáveis de ambiente

- UMAMI_URL, UMAMI_WEBSITE_ID e UMAMI_DOMAINS carregados via process.env
- script só é injetado se as vars estiverem definidas
- CSP atualizada dinamicamente com base no UMAMI_URL
- documentado no .env.example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-04-11 22:50:03 +00:00
parent e4b9dd4254
commit bf6adfa3f1
3 changed files with 21 additions and 10 deletions

View File

@@ -44,6 +44,13 @@ GOOGLE_CLIENT_SECRET=
# Se não definido, todas as rotas ficam acessíveis. # Se não definido, todas as rotas ficam acessíveis.
# PUBLIC_DOMAIN=openmonetis.com # PUBLIC_DOMAIN=openmonetis.com
# === Analytics (Opcional) ===
# Umami: https://umami.is — self-hosted ou cloud
UMAMI_URL=
UMAMI_WEBSITE_ID=
# Domínios rastreados (ex: openmonetis.com) — corresponde ao data-domains do script
UMAMI_DOMAINS=
# === AI Providers (Opcional) === # === AI Providers (Opcional) ===
ANTHROPIC_API_KEY= ANTHROPIC_API_KEY=
OPENAI_API_KEY= OPENAI_API_KEY=

View File

@@ -29,12 +29,16 @@ export default function RootLayout({
> >
<head> <head>
<meta name="apple-mobile-web-app-title" content="OpenMonetis" /> <meta name="apple-mobile-web-app-title" content="OpenMonetis" />
<script {process.env.UMAMI_URL && process.env.UMAMI_WEBSITE_ID && (
defer <script
src="https://umami.felipecoutinho.com/script.js" defer
data-website-id="ea438854-a014-42ea-b416-0a8321471f0f" src={`${process.env.UMAMI_URL}/script.js`}
data-domains="openmonetis.com" data-website-id={process.env.UMAMI_WEBSITE_ID}
/> {...(process.env.UMAMI_DOMAINS
? { "data-domains": process.env.UMAMI_DOMAINS }
: {})}
/>
)}
</head> </head>
<body className="subpixel-antialiased" suppressHydrationWarning> <body className="subpixel-antialiased" suppressHydrationWarning>
<ThemeProvider attribute="class" defaultTheme="light"> <ThemeProvider attribute="class" defaultTheme="light">

View File

@@ -34,9 +34,9 @@ function buildCsp(): string {
} }
})(); })();
const connectExtras = ["https://umami.felipecoutinho.com", s3Origin] const umamiOrigin = process.env.UMAMI_URL ?? "";
.filter(Boolean)
.join(" "); const connectExtras = [umamiOrigin, s3Origin].filter(Boolean).join(" ");
const imgExtras = ["https://lh3.googleusercontent.com", s3Origin] const imgExtras = ["https://lh3.googleusercontent.com", s3Origin]
.filter(Boolean) .filter(Boolean)
@@ -44,7 +44,7 @@ function buildCsp(): string {
return [ return [
"default-src 'self'", "default-src 'self'",
`script-src 'self' 'unsafe-inline'${isDev ? " 'unsafe-eval'" : ""} https://umami.felipecoutinho.com`, `script-src 'self' 'unsafe-inline'${isDev ? " 'unsafe-eval'" : ""}${umamiOrigin ? ` ${umamiOrigin}` : ""}`,
"style-src 'self' 'unsafe-inline'", "style-src 'self' 'unsafe-inline'",
`img-src 'self' ${imgExtras} data: blob:`, `img-src 'self' ${imgExtras} data: blob:`,
"font-src 'self'", "font-src 'self'",