integrated umami
This commit is contained in:
@@ -14,7 +14,13 @@ RUN npm ci
|
|||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
|
|
||||||
ARG NEXT_PUBLIC_SITE_URL
|
ARG NEXT_PUBLIC_SITE_URL
|
||||||
|
ARG NEXT_PUBLIC_UMAMI_SCRIPT_URL
|
||||||
|
ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID
|
||||||
|
ARG NEXT_PUBLIC_UMAMI_DOMAINS
|
||||||
ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL
|
ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL
|
||||||
|
ENV NEXT_PUBLIC_UMAMI_SCRIPT_URL=$NEXT_PUBLIC_UMAMI_SCRIPT_URL
|
||||||
|
ENV NEXT_PUBLIC_UMAMI_WEBSITE_ID=$NEXT_PUBLIC_UMAMI_WEBSITE_ID
|
||||||
|
ENV NEXT_PUBLIC_UMAMI_DOMAINS=$NEXT_PUBLIC_UMAMI_DOMAINS
|
||||||
ENV DATABASE_URL=postgresql://build:build@localhost:5432/build?schema=public
|
ENV DATABASE_URL=postgresql://build:build@localhost:5432/build?schema=public
|
||||||
|
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ AUTH_URL="https://[deine-domain.de]"
|
|||||||
NEXTAUTH_URL="https://[deine-domain.de]"
|
NEXTAUTH_URL="https://[deine-domain.de]"
|
||||||
NEXT_PUBLIC_SITE_URL="https://[deine-domain.de]"
|
NEXT_PUBLIC_SITE_URL="https://[deine-domain.de]"
|
||||||
|
|
||||||
|
# Umami Analytics (optional, cookieless)
|
||||||
|
# In Umami unter Website -> Tracking code auslesen.
|
||||||
|
NEXT_PUBLIC_UMAMI_SCRIPT_URL="https://analytics.[deine-domain.de]/script.js"
|
||||||
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID="[UMAMI_WEBSITE_ID]"
|
||||||
|
NEXT_PUBLIC_UMAMI_DOMAINS="[deine-domain.de],www.[deine-domain.de]"
|
||||||
|
|
||||||
# Mailversand via Resend
|
# Mailversand via Resend
|
||||||
RESEND_API_KEY="re_[PRODUCTION_API_KEY]"
|
RESEND_API_KEY="re_[PRODUCTION_API_KEY]"
|
||||||
EMAIL_FROM="Kita-Planer <[absender@deine-domain.de]>"
|
EMAIL_FROM="Kita-Planer <[absender@deine-domain.de]>"
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:?}
|
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:?}
|
||||||
|
NEXT_PUBLIC_UMAMI_SCRIPT_URL: ${NEXT_PUBLIC_UMAMI_SCRIPT_URL:-}
|
||||||
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID: ${NEXT_PUBLIC_UMAMI_WEBSITE_ID:-}
|
||||||
|
NEXT_PUBLIC_UMAMI_DOMAINS: ${NEXT_PUBLIC_UMAMI_DOMAINS:-}
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
PORT: 3000
|
PORT: 3000
|
||||||
@@ -14,6 +17,9 @@ services:
|
|||||||
AUTH_URL: ${AUTH_URL:?}
|
AUTH_URL: ${AUTH_URL:?}
|
||||||
NEXTAUTH_URL: ${NEXTAUTH_URL:?}
|
NEXTAUTH_URL: ${NEXTAUTH_URL:?}
|
||||||
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:?}
|
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:?}
|
||||||
|
NEXT_PUBLIC_UMAMI_SCRIPT_URL: ${NEXT_PUBLIC_UMAMI_SCRIPT_URL:-}
|
||||||
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID: ${NEXT_PUBLIC_UMAMI_WEBSITE_ID:-}
|
||||||
|
NEXT_PUBLIC_UMAMI_DOMAINS: ${NEXT_PUBLIC_UMAMI_DOMAINS:-}
|
||||||
RESEND_API_KEY: ${RESEND_API_KEY:?}
|
RESEND_API_KEY: ${RESEND_API_KEY:?}
|
||||||
EMAIL_FROM: ${EMAIL_FROM:?}
|
EMAIL_FROM: ${EMAIL_FROM:?}
|
||||||
ADMIN_EMAIL: ${ADMIN_EMAIL:?}
|
ADMIN_EMAIL: ${ADMIN_EMAIL:?}
|
||||||
|
|||||||
@@ -180,14 +180,31 @@ export default function DatenschutzPage() {
|
|||||||
<p className="mt-3 leading-7 text-slate-700">
|
<p className="mt-3 leading-7 text-slate-700">
|
||||||
Kita-Planer verwendet technisch notwendige Cookies oder
|
Kita-Planer verwendet technisch notwendige Cookies oder
|
||||||
vergleichbare Technologien, um Login-Sitzungen sicher
|
vergleichbare Technologien, um Login-Sitzungen sicher
|
||||||
bereitzustellen. [Falls Analyse- oder Marketing-Tools eingesetzt
|
bereitzustellen. Für die öffentliche Website kann zusätzlich
|
||||||
werden, hier ergänzen.]
|
Umami Analytics eingesetzt werden, um Seitenaufrufe anonymisiert
|
||||||
|
und ohne Cookies auszuwerten.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-xl font-semibold tracking-tight">
|
<h2 className="text-xl font-semibold tracking-tight">
|
||||||
8. Rechte betroffener Personen
|
8. Webanalyse mit Umami
|
||||||
|
</h2>
|
||||||
|
<p className="mt-3 leading-7 text-slate-700">
|
||||||
|
Wir nutzen [Umami-Instanz / Betreiber eintragen], um die Nutzung
|
||||||
|
der öffentlichen Website statistisch auszuwerten. Umami verwendet
|
||||||
|
keine Cookies, respektiert die Do-Not-Track-Einstellung des
|
||||||
|
Browsers und erfasst keine Analyseaufrufe im geschützten
|
||||||
|
Dashboard. Erfasst werden insbesondere Seitenaufrufe,
|
||||||
|
Referrer-Informationen, Browser-, Geräte- und Länderinformationen
|
||||||
|
in aggregierter Form. Die Rechtsgrundlage ist [Rechtsgrundlage
|
||||||
|
prüfen und eintragen].
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2 className="text-xl font-semibold tracking-tight">
|
||||||
|
9. Rechte betroffener Personen
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-3 leading-7 text-slate-700">
|
<p className="mt-3 leading-7 text-slate-700">
|
||||||
Betroffene Personen haben nach Maßgabe der DSGVO Rechte auf
|
Betroffene Personen haben nach Maßgabe der DSGVO Rechte auf
|
||||||
@@ -199,7 +216,7 @@ export default function DatenschutzPage() {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-xl font-semibold tracking-tight">
|
<h2 className="text-xl font-semibold tracking-tight">
|
||||||
9. Beschwerderecht
|
10. Beschwerderecht
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-3 leading-7 text-slate-700">
|
<p className="mt-3 leading-7 text-slate-700">
|
||||||
Betroffene Personen können sich bei einer
|
Betroffene Personen können sich bei einer
|
||||||
@@ -211,7 +228,7 @@ export default function DatenschutzPage() {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-xl font-semibold tracking-tight">
|
<h2 className="text-xl font-semibold tracking-tight">
|
||||||
10. Aktualität dieser Datenschutzerklärung
|
11. Aktualität dieser Datenschutzerklärung
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mt-3 leading-7 text-slate-700">
|
<p className="mt-3 leading-7 text-slate-700">
|
||||||
Stand: [Datum]. Wir behalten uns vor, diese Datenschutzerklärung
|
Stand: [Datum]. Wir behalten uns vor, diese Datenschutzerklärung
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { Metadata } from "next";
|
|||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import { Toaster } from "@/components/ui/sonner";
|
import { Toaster } from "@/components/ui/sonner";
|
||||||
|
import { UmamiAnalytics } from "@/components/analytics/umami-analytics";
|
||||||
|
|
||||||
const geistSans = Geist({
|
const geistSans = Geist({
|
||||||
variable: "--font-geist-sans",
|
variable: "--font-geist-sans",
|
||||||
@@ -59,6 +60,7 @@ export default function RootLayout({
|
|||||||
>
|
>
|
||||||
<body className="min-h-full flex flex-col">
|
<body className="min-h-full flex flex-col">
|
||||||
{children}
|
{children}
|
||||||
|
<UmamiAnalytics />
|
||||||
<Toaster />
|
<Toaster />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import Script from "next/script";
|
||||||
|
|
||||||
|
const publicAnalyticsPaths = new Set([
|
||||||
|
"/",
|
||||||
|
"/impressum",
|
||||||
|
"/datenschutz",
|
||||||
|
"/login",
|
||||||
|
"/register",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export function UmamiAnalytics() {
|
||||||
|
const scriptUrl = process.env.NEXT_PUBLIC_UMAMI_SCRIPT_URL;
|
||||||
|
const websiteId = process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID;
|
||||||
|
const domains = process.env.NEXT_PUBLIC_UMAMI_DOMAINS;
|
||||||
|
|
||||||
|
if (!scriptUrl || !websiteId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Script id="umami-before-send" strategy="afterInteractive">
|
||||||
|
{`
|
||||||
|
window.kitaPlanerUmamiBeforeSend = function (_type, payload) {
|
||||||
|
try {
|
||||||
|
var url = new URL(payload && payload.url ? payload.url : window.location.href, window.location.origin);
|
||||||
|
var path = url.pathname.length > 1 && url.pathname.endsWith("/") ? url.pathname.slice(0, -1) : url.pathname;
|
||||||
|
var allowedPaths = ${JSON.stringify(Array.from(publicAnalyticsPaths))};
|
||||||
|
return allowedPaths.indexOf(path) === -1 ? false : payload;
|
||||||
|
} catch (_error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
`}
|
||||||
|
</Script>
|
||||||
|
<Script
|
||||||
|
src={scriptUrl}
|
||||||
|
strategy="afterInteractive"
|
||||||
|
data-website-id={websiteId}
|
||||||
|
data-domains={domains}
|
||||||
|
data-exclude-search="true"
|
||||||
|
data-exclude-hash="true"
|
||||||
|
data-do-not-track="true"
|
||||||
|
data-before-send="kitaPlanerUmamiBeforeSend"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user