Aller au contenu principal
8 min de lecture

Suivi du trafic au premier niveau avec Astro

Configurez un proxy au premier niveau dans votre projet Astro en utilisant des routes API. Fonctionne avec les modes static et SSR.

Difficulté : Facile - Ajoutez un fichier de route API à votre projet.

Pourquoi cela fonctionne (Même origine)

Cette approche utilise /api/_z/script.js qui se trouve sur la même origine que votre site web. Firefox ETP et les autres protections de suivi bloquent uniquement les requêtes cross-origin.

  • Le navigateur voit : yourdomain.com/api/_z/script.js — même origine, pas de blocage cross-origin
  • La route API d'Astro proxie la requête vers le serveur Zenovay (le navigateur ne voit jamais ceci)
  • Toute la protection contre le suivi est contournée car la requête est au premier niveau

Avant de commencer

Assurez-vous que vous disposez de :

  • Un projet Astro (v2.0+ recommandé)
  • Votre code de suivi Zenovay (trouvé sous Domaines → votre domaine → Général)
  • Un adaptateur SSR installé (pour Vercel, Netlify, Cloudflare, Node, etc.)

Format de votre code de suivi

Votre code de suivi ressemble à : ZV_XXXXXXXXXX

  • Commence par ZV_
  • Suivi de 10 caractères (lettres et chiffres)
  • CAS SENSIBLE - copiez-le exactement

Exemple : ZV_Q8U0GYD70WR

La carte de script de suivi montrant l'extrait de script avec les onglets HTML, React, Next.js et First-Party
Trouvez votre code de suivi dans l'onglet First-Party sous Domaines → votre domaine → Général.

Sites statiques : Si vous utilisez output: 'static', les routes API d'Astro ne fonctionneront pas. Utilisez plutôt le proxy de votre plateforme d'hébergement (rewrites Vercel, redirects Netlify, etc.).


Étape 1 : Activer SSR (si ce n'est pas déjà fait)

Tout d'abord, assurez-vous que votre projet Astro a SSR activé avec un adaptateur.

Pour Vercel

TerminalBash
npm install @astrojs/vercel
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
output: 'server', // or 'hybrid' for partial SSR
adapter: vercel(),
});

Pour Netlify

TerminalBash
npm install @astrojs/netlify
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';

export default defineConfig({
output: 'server',
adapter: netlify(),
});

Pour Cloudflare

TerminalBash
npm install @astrojs/cloudflare
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
output: 'server',
adapter: cloudflare(),
});

Pour Node.js

TerminalBash
npm install @astrojs/node
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
output: 'server',
adapter: node({
  mode: 'standalone'
}),
});

Étape 2 : Créer la route API Proxy

Créez une route API catch-all qui proxie les requêtes vers Zenovay :

src/pages/api/_z/[...path].tsTypeScript
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' },
  })
}
}

Pourquoi [...path].ts ? La syntaxe spread crée une route catch-all qui capture plusieurs segments de chemin. Cela signifie que /api/_z/script.js, /api/_z/e/CODE et /api/_z/settings/CODE sont tous routés vers ce fichier unique.


Étape 3 : Ajouter le script de suivi

Ajoutez le script de suivi à votre mise en page :

src/layouts/Layout.astroASTRO
---
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>

Important : Remplacez YOUR_TRACKING_CODE par votre code de suivi réel du tableau de bord Zenovay.


Étape 4 : Déployer

Déployez votre projet Astro sur la plateforme de votre choix :

TerminalBash
# Build the project
npm run build

# Deploy (depends on your adapter)
# Vercel: vercel deploy
# Netlify: netlify deploy --prod
# Cloudflare: wrangler pages deploy dist

Mode hybride (Recommandé)

Si la plupart de votre site est statique mais que vous avez besoin du proxy, utilisez le mode hybride :

astro.config.mjsJavaScript
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(),
});

Puis marquez la route API pour le rendu serveur :

src/pages/api/_z/[...path].tsTypeScript
// 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
}

Vérifier que cela fonctionne

Vérifier l'onglet Réseau

  1. Visitez votre site déployé
  2. Ouvrez DevTools (F12)
  3. Allez à l'onglet Réseau
  4. Rechargez la page
  5. Cherchez /api/_z/script.js

Vous devriez voir :

  • Statut : 200
  • Domaine : Votre domaine
  • Réponse : Code JavaScript

Test dans Firefox

  1. Ouvrez Firefox
  2. Paramètres → Confidentialité et sécurité → Protection contre le suivi renforcée : Strict
  3. Visitez votre site
  4. Vérifiez que le script se charge correctement

Dépannage

Erreur 404 sur la route API

Cause : SSR n'est pas activé ou l'adaptateur n'est pas configuré.

Solution :

  1. Assurez-vous que vous avez output: 'server' ou output: 'hybrid' dans astro.config.mjs
  2. Vérifiez que vous avez un adaptateur installé et configuré
  3. Pour le mode hybride, ajoutez export const prerender = false; à la route API

Erreur 500

Cause : Erreur de syntaxe ou problème à l'exécution dans la route API.

Solution :

  1. Vérifiez les journaux du serveur pour les messages d'erreur détaillés
  2. Assurez-vous que les types TypeScript sont corrects
  3. Vérifiez que tous les imports sont disponibles

Le script se charge mais pas de données

Cause : Code de suivi ne correspond pas.

Solution :

  1. Vérifiez que data-tracking-code correspond à votre code dans le tableau de bord Zenovay
  2. Vérifiez la console du navigateur pour les erreurs JavaScript
  3. Assurez-vous que le domaine est enregistré dans Zenovay

Géolocalisation incorrecte

Cause : L'IP du client n'est pas transmise correctement.

Solution : La route API essaie plusieurs en-têtes. Assurez-vous que votre plateforme en transmet un parmi :

  • x-forwarded-for (plus courant)
  • cf-connecting-ip (Cloudflare)
  • x-real-ip (nginx)

Alternative pour sites statiques

Si vous utilisez output: 'static', vous ne pouvez pas utiliser les routes API. Utilisez plutôt le proxy de votre plateforme d'hébergement :

Vercel

vercel.jsonJSON
{
"rewrites": [
  { "source": "/api/_z/:path*", "destination": "https://api.zenovay.com/fp/:path*" }
]
}

Netlify

public/_redirectsTEXT
/api/_z/*  https://api.zenovay.com/fp/:splat  200

Cloudflare Pages

Utilisez plutôt les Cloudflare Pages Functions - consultez le guide Cloudflare Pages.


Exemple complet

Project StructureTEXT
my-astro-site/
├── astro.config.mjs
├── src/
│   ├── layouts/
│   │   └── Layout.astro
│   └── pages/
│       ├── index.astro
│       └── api/
│           └── _z/
│               └── [...path].ts
└── package.json
astro.config.mjsJavaScript
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
output: 'hybrid',
adapter: vercel(),
});
src/layouts/Layout.astroASTRO
---
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>

Liste de contrôle finale

Avant de terminer, vérifiez tous ces points :

  • Astro SSR est activé (ou utilise rewrites de plateforme statique)
  • Le fichier de route API existe à src/pages/api/_z/[...path].ts
  • export const prerender = false est défini (pour le mode hybride)
  • La balise script utilise /api/_z/script.js (pas l'URL Zenovay directe)
  • L'attribut data-tracking-code contient votre code de suivi correct
  • Le projet est déployé (pas seulement exécuté localement)
  • Testé dans Firefox avec Protection contre le suivi renforcée définie à Strict
  • Les visites apparaissent dans le tableau de bord Zenovay

Prochaines étapes

Cette page vous a-t-elle été utile ?