diff --git a/Dockerfile b/Dockerfile index d5c65ec..923a136 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,7 +49,6 @@ RUN node_modules/.bin/prisma generate ARG NEXT_PUBLIC_APP_NAME ARG NEXT_PUBLIC_APP_DESCRIPTION ARG NEXT_PUBLIC_DOMAIN -ARG NEXT_PUBLIC_PLAUSIBLE_DOMAIN ARG NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC ARG NEXT_PUBLIC_THEME_COLOR ARG NEXT_PUBLIC_BACKGROUND_COLOR @@ -62,7 +61,6 @@ ARG NEXT_PUBLIC_CREDITS_LINK_URL ENV NEXT_PUBLIC_APP_NAME=$NEXT_PUBLIC_APP_NAME ENV NEXT_PUBLIC_APP_DESCRIPTION=$NEXT_PUBLIC_APP_DESCRIPTION ENV NEXT_PUBLIC_DOMAIN=$NEXT_PUBLIC_DOMAIN -ENV NEXT_PUBLIC_PLAUSIBLE_DOMAIN=$NEXT_PUBLIC_PLAUSIBLE_DOMAIN ENV NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC=$NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC ENV NEXT_PUBLIC_THEME_COLOR=$NEXT_PUBLIC_THEME_COLOR ENV NEXT_PUBLIC_BACKGROUND_COLOR=$NEXT_PUBLIC_BACKGROUND_COLOR diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx index 7fa70a1..88d659c 100644 --- a/app/[locale]/layout.tsx +++ b/app/[locale]/layout.tsx @@ -5,6 +5,7 @@ import "../globals.css"; // Adjusted path import { NextIntlClientProvider } from 'next-intl'; import { getMessages } from 'next-intl/server'; import { notFound } from 'next/navigation'; +import { headers } from 'next/headers'; import { config } from "@/lib/config"; import InstallPrompt from "@/components/InstallPrompt"; @@ -52,12 +53,32 @@ export default async function LocaleLayout({ // Providing all messages to the client const messages = await getMessages(); + // Get current domain from request headers for dynamic Plausible tracking + // This automatically tracks the correct domain (hoerdle.de or hördle.de) + const headersList = await headers(); + const host = headersList.get('host') || headersList.get('x-forwarded-host') || ''; + + // Automatically detect which domain to track in Plausible based on the request + let plausibleDomain = 'hoerdle.de'; // Default fallback + + if (host) { + // Extract domain from host (remove port if present) + const domain = host.split(':')[0].toLowerCase(); + + // Map domains: automatically track the current domain + if (domain === 'hoerdle.de') { + plausibleDomain = 'hoerdle.de'; + } else if (domain === 'hördle.de' || domain === 'xn--hrdle-jua.de') { + plausibleDomain = 'hördle.de'; + } + } + return (
diff --git a/docker-compose.example.yml b/docker-compose.example.yml index e0a544b..094fd43 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -8,7 +8,6 @@ services: NEXT_PUBLIC_APP_NAME: ${NEXT_PUBLIC_APP_NAME} NEXT_PUBLIC_APP_DESCRIPTION: ${NEXT_PUBLIC_APP_DESCRIPTION} NEXT_PUBLIC_DOMAIN: ${NEXT_PUBLIC_DOMAIN} - NEXT_PUBLIC_PLAUSIBLE_DOMAIN: ${NEXT_PUBLIC_PLAUSIBLE_DOMAIN} NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC: ${NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC} NEXT_PUBLIC_THEME_COLOR: ${NEXT_PUBLIC_THEME_COLOR} NEXT_PUBLIC_BACKGROUND_COLOR: ${NEXT_PUBLIC_BACKGROUND_COLOR} diff --git a/docs/PLAUSIBLE_SETUP.md b/docs/PLAUSIBLE_SETUP.md new file mode 100644 index 0000000..adf873d --- /dev/null +++ b/docs/PLAUSIBLE_SETUP.md @@ -0,0 +1,167 @@ +# Plausible Analytics Konfiguration + +## Übersicht + +Die App verwendet Plausible Analytics für anonyme Nutzungsstatistiken. Die Konfiguration erfolgt über Umgebungsvariablen. + +## Konfiguration + +### Erforderliche Variablen + +**Nur eine Variable ist erforderlich:** + +1. **`NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC`** (erforderlich) + - Die vollständige URL zum Plausible-Script + - Beispiel (selbst gehostet): `https://plausible.elpatron.me/js/script.js` + - Beispiel (extern): `https://plausible.io/js/script.js` + +**Hinweis:** Die Domain wird automatisch aus der Request-Domain erkannt. Beide Domains (`hoerdle.de` und `hördle.de`) werden automatisch getrackt. + +### Konfiguration für Docker + +Da es sich um **Build-Time Variablen** handelt (NEXT_PUBLIC_*), muss die App neu gebaut werden, wenn diese geändert werden. + +#### Schritt 1: Umgebungsvariablen setzen + +Erstelle oder bearbeite eine `.env`-Datei im Projektverzeichnis: + +```bash +# Plausible Analytics (Script-URL ist erforderlich) +NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC=https://plausible.elpatron.me/js/script.js + +# Die Domain wird automatisch erkannt - keine weitere Konfiguration nötig! +``` + +#### Schritt 2: docker-compose.yml konfigurieren + +Stelle sicher, dass die Variablen als Build-Args übergeben werden: + +```yaml +services: + hoerdle: + build: + context: . + dockerfile: Dockerfile + args: + NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC: ${NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC} +``` + +Die `docker-compose.example.yml` enthält bereits diese Konfiguration. + +#### Schritt 3: App neu bauen + +**WICHTIG:** Nach Änderung der Plausible-Variablen muss die App neu gebaut werden: + +```bash +docker compose build --no-cache +docker compose up -d +``` + +Oder mit dem Deploy-Script: + +```bash +./scripts/deploy.sh +``` + +### Konfiguration für beide Domains + +Die App unterstützt **automatisches Tracking** für beide Domains (`hoerdle.de` und `hördle.de`). Die Domain wird automatisch aus dem Request-Header ausgelesen und entsprechend in Plausible getrackt. + +#### Automatisches Domain-Tracking + +**Standard-Verhalten:** Die App erkennt automatisch, welche Domain aufgerufen wurde, und setzt die entsprechende `data-domain` im Plausible-Script: +- `https://hoerdle.de/*` → `data-domain="hoerdle.de"` +- `https://hördle.de/*` → `data-domain="hördle.de"` + +#### In Plausible konfigurieren + +Du hast zwei Optionen: + +##### Option 1: Beide Domains als separate Sites (separate Statistiken) - Empfohlen für getrenntes Tracking + +1. Erstelle in Plausible zwei separate Sites: + - `hoerdle.de` + - `hördle.de` + +2. Fertig! Die App trackt automatisch die richtige Domain. + +**Vorteil:** Separate Statistiken für jede Domain. + +##### Option 2: Beide Domains als Aliase für eine Site (gemeinsame Statistiken) + +1. Erstelle in Plausible eine Site: `hoerdle.de` +2. Füge `hördle.de` als Alias hinzu (in den Site-Einstellungen) + +3. Fertig! Die App trackt automatisch die richtige Domain, und Plausible behandelt beide als Aliase für die gleiche Site. + +**Hinweis:** Du musst nichts zusätzlich konfigurieren. Die App trackt automatisch `hoerdle.de` oder `hördle.de` basierend auf der Request-Domain, und Plausible erkennt beide als Aliase. + +**Vorteil:** Gemeinsame Statistiken für beide Domains in einer Site. + +#### Empfehlung + +Für separate Statistiken: **Option 1** (automatisches Tracking) +Für gemeinsame Statistiken: **Option 2** (Aliase in Plausible) + +### Automatische CSP-Anpassung + +Die Content Security Policy (CSP) in `proxy.ts` wird automatisch an die konfigurierte Plausible-URL angepasst. Die Domain wird automatisch aus der Script-URL extrahiert. + +### Prüfen der Konfiguration + +Nach dem Neubau kannst du prüfen, ob Plausible korrekt geladen wird: + +1. **Browser-Entwicklertools öffnen** + - Network-Tab: Suche nach dem Plausible-Script + - Console: Prüfe auf Fehler + +2. **Prüfe die Meta-Tags** + ```html + + ``` + +3. **Prüfe Plausible-Dashboard** + - Öffne dein Plausible-Dashboard + - Prüfe, ob Daten ankommen + +### Troubleshooting + +#### Plausible wird nicht geladen + +- Prüfe, ob die Umgebungsvariablen korrekt gesetzt sind +- Prüfe, ob die App neu gebaut wurde (Build-Time Variablen!) +- Prüfe Browser-Console auf CSP-Fehler + +#### CSP blockiert Plausible + +Die CSP sollte automatisch angepasst werden. Falls Probleme auftreten: +- Prüfe, ob `NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC` korrekt gesetzt ist +- Prüfe die Logs des Containers + +#### Daten werden nicht in Plausible angezeigt + +- Prüfe, ob die Domain in Plausible als Site konfiguriert ist +- Prüfe, ob `data-domain` Attribut mit der konfigurierten Domain übereinstimmt +- Prüfe Browser-Console auf Fehler beim Laden des Scripts + +### Beispiel-Konfiguration + +#### Für selbst gehostetes Plausible: + +```bash +NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC=https://plausible.elpatron.me/js/script.js +``` + +#### Für Plausible.io (extern): + +```bash +NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC=https://plausible.io/js/script.js +``` + +**Hinweis:** Die Domain wird automatisch aus der Request-Domain erkannt - keine weitere Konfiguration nötig! + +### Weitere Informationen + +- [Plausible Dokumentation](https://plausible.io/docs) +- [Plausible Self-Hosting](https://plausible.io/docs/self-hosting) + diff --git a/docs/WHITE_LABEL.md b/docs/WHITE_LABEL.md index 69ac3a9..77b4027 100644 --- a/docs/WHITE_LABEL.md +++ b/docs/WHITE_LABEL.md @@ -18,9 +18,10 @@ The application is configured via environment variables. You can set these in a | Variable | Description | Default | |----------|-------------|---------| -| `NEXT_PUBLIC_PLAUSIBLE_DOMAIN` | The domain to track in Plausible. | `hoerdle.de` | | `NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC` | The URL of the Plausible script. | `https://plausible.example.com/js/script.js` | +**Hinweis:** Die Domain wird automatisch aus der Request-Domain erkannt. Beide Domains (`hoerdle.de` und `hördle.de`) werden automatisch getrackt. + ### Credits | Variable | Description | Default | diff --git a/lib/config.ts b/lib/config.ts index 37c947b..ca3d593 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -2,7 +2,6 @@ export const config = { appName: process.env.NEXT_PUBLIC_APP_NAME || 'Hördle', appDescription: process.env.NEXT_PUBLIC_APP_DESCRIPTION || 'Daily music guessing game - Guess the song from short audio clips', domain: process.env.NEXT_PUBLIC_DOMAIN || 'hoerdle.de', - plausibleDomain: process.env.NEXT_PUBLIC_PLAUSIBLE_DOMAIN || 'hoerdle.de', plausibleScriptSrc: process.env.NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC || 'https://plausible.example.com/js/script.js', colors: { themeColor: process.env.NEXT_PUBLIC_THEME_COLOR || '#000000',