Compare commits

...

2 commits

Author SHA1 Message Date
89ce5e2c0b Merge pull request 'feat(web): optional Umami analytics (env-driven)' (#21) from feature/umami-analytics into dev
Reviewed-on: #21
2026-06-15 06:49:33 +00:00
AyoubBenziza
1bda0e122e feat(web): optional Umami analytics (env-driven)
- inject the Umami script at runtime only when VITE_UMAMI_SRC + VITE_UMAMI_WEBSITE_ID
  are set (so dev/local traffic isn't tracked); website-id is public, not a secret
- web Dockerfile passes them as build args; docker-compose.prod.yml + env examples
  document them (optional, empty = disabled)

Verified: build bakes the values in when set; skipped when unset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 08:40:35 +02:00
5 changed files with 34 additions and 0 deletions

View file

@ -1 +1,5 @@
VITE_SERVER_URL=http://localhost:3001
# Umami analytics (optionnel, prod). Vide en dev = pas de suivi.
VITE_UMAMI_SRC=
VITE_UMAMI_WEBSITE_ID=

View file

@ -15,6 +15,11 @@ COPY apps/web apps/web
ARG VITE_SERVER_URL
ENV VITE_SERVER_URL=$VITE_SERVER_URL
# Umami analytics (optionnel) — figé au build.
ARG VITE_UMAMI_SRC
ENV VITE_UMAMI_SRC=$VITE_UMAMI_SRC
ARG VITE_UMAMI_WEBSITE_ID
ENV VITE_UMAMI_WEBSITE_ID=$VITE_UMAMI_WEBSITE_ID
RUN bun run --filter web build
FROM nginx:1.27-alpine AS runner

View file

@ -0,0 +1,20 @@
// Umami analytics : on injecte le script seulement si les variables de build
// sont présentes (donc pas en dev → pas de trafic local dans les stats).
// L'ID de site est public (visible dans le HTML), ce n'est pas un secret.
const SRC = import.meta.env.VITE_UMAMI_SRC
const WEBSITE_ID = import.meta.env.VITE_UMAMI_WEBSITE_ID
export function initAnalytics(): void {
if (!SRC || !WEBSITE_ID) {
return
}
if (document.querySelector("script[data-website-id]")) {
return
}
const script = document.createElement("script")
script.defer = true
script.src = SRC
script.setAttribute("data-website-id", WEBSITE_ID)
document.head.appendChild(script)
}

View file

@ -6,6 +6,9 @@ import "@workspace/ui/globals.css"
import { App } from "./App.tsx"
import { ThemeProvider } from "@/components/theme-provider.tsx"
import { I18nProvider } from "@/i18n/provider"
import { initAnalytics } from "@/lib/analytics"
initAnalytics()
const queryClient = new QueryClient()

View file

@ -54,6 +54,8 @@ services:
dockerfile: apps/web/Dockerfile
args:
VITE_SERVER_URL: ${VITE_SERVER_URL}
VITE_UMAMI_SRC: ${VITE_UMAMI_SRC:-}
VITE_UMAMI_WEBSITE_ID: ${VITE_UMAMI_WEBSITE_ID:-}
restart: unless-stopped
depends_on:
- server