First-Party Tracking mit Astro
Richte einen First-Party-Proxy in deinem Astro-Projekt mit API-Routen ein. Funktioniert sowohl mit statischen als auch mit SSR-Modi.
Schwierigkeit: Einfach - Füge eine API-Routen-Datei zu deinem Projekt hinzu.
Warum das funktioniert (gleicher Ursprung)
Dieser Ansatz nutzt /api/_z/script.js, das sich auf dem gleichen Ursprung wie deine Website befindet. Firefox ETP und andere Tracking-Schutzmaßnahmen blockieren nur Cross-Origin-Anfragen.
- Browser sieht:
yourdomain.com/api/_z/script.js— gleicher Ursprung, kein Cross-Origin-Block - Astros API-Route leitet die Anfrage serverseitig an den Zenovay-Server weiter (Browser sieht das nicht)
- Der gesamte Tracking-Schutz wird umgangen, da die Anfrage First-Party ist
Bevor du loslegst
Stelle sicher, dass du folgendes hast:
- Ein Astro-Projekt (v2.0+ empfohlen)
- Deinen Zenovay-Tracking-Code (zu finden unter Domains → deine Domain → General)
- SSR-Adapter installiert (für Vercel, Netlify, Cloudflare, Node, etc.)
Dein Tracking-Code-Format
Dein Tracking-Code sieht so aus: ZV_XXXXXXXXXX
- Beginnt mit
ZV_ - Gefolgt von 10 Zeichen (Buchstaben und Zahlen)
- CASE-SENSITIVE - kopiere ihn genau
Beispiel: ZV_Q8U0GYD70WR

Statische Websites: Wenn du output: 'static' nutzt, funktionieren Astro API-Routen nicht. Nutze stattdessen den Proxy deiner Hosting-Plattform (Vercel-Rewrites, Netlify-Redirects, etc.).
Schritt 1: Aktiviere SSR (falls noch nicht geschehen)
Stelle zunächst sicher, dass SSR in deinem Astro-Projekt mit einem Adapter aktiviert ist.
Für Vercel
npm install @astrojs/vercelimport { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
output: 'server', // oder 'hybrid' für partielles SSR
adapter: vercel(),
});Für Netlify
npm install @astrojs/netlifyimport { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';
export default defineConfig({
output: 'server',
adapter: netlify(),
});Für Cloudflare
npm install @astrojs/cloudflareimport { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'server',
adapter: cloudflare(),
});Für Node.js
npm install @astrojs/nodeimport { defineConfig } from 'astro/config';
import node from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: node({
mode: 'standalone'
}),
});Schritt 2: Erstelle die Proxy API-Route
Erstelle eine Catch-All-API-Route, die Anfragen an Zenovay weiterleitet:
import type { APIRoute } from 'astro'
export const ALL: APIRoute = async ({ params, request }) => {
// Build the path from the catch-all parameter
const path = params.path || ''
const url = new URL(request.url)
const targetUrl = `https://api.zenovay.com/fp/${path}${url.search}`
// Handle CORS preflight requests
if (request.method === 'OPTIONS') {
return new Response(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
})
}
try {
// Get the real client IP for accurate geolocation
const clientIP = request.headers.get('x-forwarded-for')?.split(',')[0]
|| request.headers.get('cf-connecting-ip')
|| request.headers.get('x-real-ip')
|| ''
// Build proxy headers
const headers = new Headers()
headers.set('Content-Type', request.headers.get('Content-Type') || 'application/json')
headers.set('X-Zenovay-Real-IP', clientIP)
// Forward the request
const response = await fetch(targetUrl, {
method: request.method,
headers: headers,
body: request.method !== 'GET' ? await request.text() : undefined,
})
// Build response with CORS headers
const responseHeaders = new Headers(response.headers)
responseHeaders.set('Access-Control-Allow-Origin', '*')
return new Response(response.body, {
status: response.status,
headers: responseHeaders,
})
} catch (error) {
console.error('Proxy error:', error)
return new Response(JSON.stringify({ error: 'Proxy error' }), {
status: 502,
headers: { 'Content-Type': 'application/json' },
})
}
}Warum [...path].ts? Die Spread-Syntax erstellt eine Catch-All-Route, die mehrere Pfad-Segmente erfasst. Das bedeutet /api/_z/script.js, /api/_z/e/CODE und /api/_z/settings/CODE werden alle zu dieser einzelnen Datei geroutet.
Schritt 3: Füge das Tracking-Skript hinzu
Füge das Tracking-Skript zu deinem Layout hinzu:
---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
<!-- Zenovay Analytics (First-Party Proxy) -->
<script defer data-tracking-code="YOUR_TRACKING_CODE" src="/api/_z/script.js"></script>
</head>
<body>
<slot />
</body>
</html>Wichtig: Ersetze YOUR_TRACKING_CODE durch deinen aktuellen Tracking-Code aus dem Zenovay-Dashboard.
Schritt 4: Stelle bereit
Stellen Sie dein Astro-Projekt auf deiner gewählten Plattform bereit:
# Build the project
npm run build
# Deploy (depends on your adapter)
# Vercel: vercel deploy
# Netlify: netlify deploy --prod
# Cloudflare: wrangler pages deploy distHybrid-Modus (Empfohlen)
Wenn der Großteil deiner Website statisch ist, aber du den Proxy benötigst, nutze den Hybrid-Modus:
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
output: 'hybrid', // Static by default, SSR for specific routes
adapter: vercel(),
});Markiere dann die API-Route für das Server-Rendering:
// Force server rendering for this route
export const prerender = false;
import type { APIRoute } from 'astro'
export const ALL: APIRoute = async ({ params, request }) => {
// ... rest of the proxy code
}Überprüfe, ob es funktioniert
Überprüfe den Netzwerk-Reiter
- Besuche deine bereitgestellte Website
- Öffne die Entwicklertools (F12)
- Gehe zum Reiter Network
- Lade die Seite neu
- Suche nach
/api/_z/script.js
Du solltest sehen:
- Status: 200
- Domain: Deine Domain
- Response: JavaScript-Code
Teste in Firefox
- Öffne Firefox
- Einstellungen → Datenschutz & Sicherheit → Verbesserter Tracking-Schutz: Streng
- Besuche deine Website
- Überprüfe, dass das Skript erfolgreich geladen wird
Fehlerbehebung
404-Fehler in der API-Route
Ursache: SSR nicht aktiviert oder Adapter nicht konfiguriert.
Lösung:
- Stelle sicher, dass du
output: 'server'oderoutput: 'hybrid'inastro.config.mjshast - Überprüfe, dass du einen Adapter installiert und konfiguriert hast
- Füge im Hybrid-Modus
export const prerender = false;zur API-Route hinzu
500-Fehler
Ursache: Syntaxfehler oder Laufzeitproblem in der API-Route.
Lösung:
- Überprüfe die Server-Logs auf detaillierte Fehlermeldungen
- Stelle sicher, dass TypeScript-Typen korrekt sind
- Überprüfe, dass alle Importe verfügbar sind
Skript wird geladen, aber keine Daten
Ursache: Tracking-Code stimmt nicht überein.
Lösung:
- Überprüfe, dass
data-tracking-codemit deinem Code im Zenovay-Dashboard übereinstimmt - Überprüfe die Browser-Konsole auf JavaScript-Fehler
- Stelle sicher, dass die Domain in Zenovay registriert ist
Geolokalisierung falsch
Ursache: Client-IP wird nicht korrekt weitergeleitet.
Lösung: Die API-Route versucht mehrere Header. Stelle sicher, dass deine Plattform einen davon weiterleitet:
x-forwarded-for(am häufigsten)cf-connecting-ip(Cloudflare)x-real-ip(nginx)
Alternative für statische Websites
Wenn du output: 'static' verwendest, kannst du keine API-Routen verwenden. Verwende stattdessen den Proxy deiner Hosting-Plattform:
Vercel
{
"rewrites": [
{ "source": "/api/_z/:path*", "destination": "https://api.zenovay.com/fp/:path*" }
]
}Netlify
/api/_z/* https://api.zenovay.com/fp/:splat 200Cloudflare Pages
Nutze stattdessen Cloudflare Pages Functions - siehe das Cloudflare Pages-Handbuch.
Vollständiges Beispiel
my-astro-site/
├── astro.config.mjs
├── src/
│ ├── layouts/
│ │ └── Layout.astro
│ └── pages/
│ ├── index.astro
│ └── api/
│ └── _z/
│ └── [...path].ts
└── package.jsonimport { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
output: 'hybrid',
adapter: vercel(),
});---
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>{title}</title>
<script defer data-tracking-code="YOUR_TRACKING_CODE" src="/api/_z/script.js"></script>
</head>
<body>
<slot />
</body>
</html>Abschließende Checkliste
Überprüfe vor Abschluss alle diese Punkte:
- Astro SSR ist aktiviert (oder du verwendest statische Website-Plattform-Rewrites)
- API-Routen-Datei existiert unter
src/pages/api/_z/[...path].ts -
export const prerender = falseist gesetzt (für Hybrid-Modus) - Skript-Tag verwendet
/api/_z/script.js(nicht die direkte Zenovay-URL) -
data-tracking-codeAttribut enthält deinen korrekten Tracking-Code - Projekt ist bereitgestellt (nicht nur lokal ausgeführt)
- In Firefox mit verbessertem Tracking-Schutz auf Stufe Streng getestet
- Besuche erscheinen im Zenovay-Dashboard
Nächste Schritte
- Custom Events - Verfolgung von Benutzerinteraktionen
- Visitor Identification - Verknüpfe Analytics mit Benutzern
- Troubleshooting - Weitere Hilfe bei Problemen