Aller au contenu
wheremyflow
Fonctionnalités Tarifs Comparatif Manifeste Aide Audit Contact Démo Connexion

Self-host le tracker (anti-blocage)

Chrome 121+, uBlock Origin, Brave Shields, AdGuard et la plupart des bloqueurs publicitaires bloquent par défaut les requêtes vers tout domaine tiers étiqueté « analytics », même quand le service ne fait aucun tracking publicitaire (c'est notre cas).

Sans rien faire, vous perdez aujourd'hui 5 à 20 % des sessions, et la part montera à 30-50 % d'ici 12 à 24 mois quand Chrome appliquera la _Tracking Protection_ à toutes les sessions normales (pas seulement la navigation privée).

La solution : servir le tracker et l'API depuis votre propre domaine. Le navigateur voit alors une requête « 1st-party » indistinguable d'un appel à une image ou une feuille de style. Aucun bloqueur ne bloque ça.

Cette page documente comment faire avec des outils strictement souverains UE. Aucune des recettes ci-dessous ne dépend d'un fournisseur soumis au _Cloud Act_ américain.


Comment ça marche, schéma général

┌──────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│   AVANT (3rd-party, bloqué)                                              │
│   ──────────────────────                                                 │
│                                                                          │
│   navigateur ──► <script src="https://wheremyflow.com/w.js">             │
│                  ❌ ERR_BLOCKED_BY_CLIENT                                 │
│                                                                          │
│   navigateur ──► POST https://wheremyflow.com/api/event                  │
│                  ❌ ERR_BLOCKED_BY_CLIENT                                 │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│   APRÈS (1st-party via votre proxy, jamais bloqué)                       │
│   ────────────────────────────────────────────                           │
│                                                                          │
│   navigateur ──► <script src="/js/flow.js"> sur monsite.com              │
│                  ✅ servi par votre proxy depuis wheremyflow.com         │
│                                                                          │
│   navigateur ──► POST monsite.com/api/event                              │
│                  ✅ relayé par votre proxy vers wheremyflow.com          │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘

Vous proxifiez 3 endpoints depuis votre domaine vers wheremyflow.com :

| Chemin sur votre domaine | Cible chez wheremyflow | Rôle | | ------------------------ | --------------------------- | ------------------------------ | | /js/flow.js | wheremyflow.com/w.js | Script du tracker | | /api/event | wheremyflow.com/api/event | Pageviews + événements custom | | /api/ping | wheremyflow.com/api/ping | Heartbeat « live » toutes 30 s | | /api/zone | wheremyflow.com/api/zone | Zones de scroll (lecture) |

Le snippet à coller dans votre <head> devient :

<script defer src="/js/flow.js" data-site="monsite.com"></script>

Tous les chemins sont en 1st-party, aucun ne sort vers un domaine tiers depuis le navigateur. Côté serveur, votre proxy fait le pont avec wheremyflow.com de manière transparente.

Important — préservation de l'IP visiteur : votre proxy doit transmettre l'header X-Forwarded-For correctement, sinon la géolocalisation côté wheremyflow tombe sur l'IP de votre proxy au lieu de celle du visiteur. Chaque recette ci-dessous l'inclut explicitement.

Recette 1 — Nginx (la plus universelle)

Fonctionne sur : tout VPS Linux (OVH, Scaleway, Hetzner, Clever Cloud avec runtime Nginx, IONOS, Infomaniak, etc.).

Souveraineté : neutre (dépend de votre hébergeur ; choisissez UE).

Ajoutez ce bloc dans votre fichier de configuration Nginx, à l'intérieur du server { ... } qui sert votre site (typiquement /etc/nginx/sites-available/monsite.conf) :

# wheremyflow — proxy 1st-party (anti-blocage)
location = /js/flow.js {
    proxy_pass        https://wheremyflow.com/w.js;
    proxy_set_header  Host wheremyflow.com;
    proxy_ssl_server_name on;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  X-Real-IP       $remote_addr;
    proxy_set_header  User-Agent      $http_user_agent;
    proxy_set_header  Accept-Language $http_accept_language;
    proxy_hide_header Set-Cookie;
    proxy_read_timeout 10s;
}

location ~ ^/api/(event|ping|zone)$ {
    proxy_pass        https://wheremyflow.com$request_uri;
    proxy_set_header  Host wheremyflow.com;
    proxy_ssl_server_name on;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  X-Real-IP       $remote_addr;
    proxy_set_header  User-Agent      $http_user_agent;
    proxy_set_header  Accept-Language $http_accept_language;
    proxy_set_header  Origin          $http_origin;
    proxy_hide_header Set-Cookie;
    proxy_read_timeout 10s;
}

Puis testez et rechargez :

sudo nginx -t && sudo systemctl reload nginx

Vérification : depuis votre navigateur, ouvrez https://monsite.com/js/flow.js — vous devez voir le code du tracker minifié. Si erreur 502, vérifiez que proxy_ssl_server_name on; est bien présent (obligatoire pour le SNI vers wheremyflow.com).


Recette 2 — Caddy (la plus simple)

Fonctionne sur : tout serveur où Caddy tourne (auto-TLS inclus).

Souveraineté : neutre (dépend de votre hébergeur).

Dans votre Caddyfile, à l'intérieur du bloc de votre site :

monsite.com {
    # ... votre config existante ...

    # wheremyflow — proxy 1st-party (anti-blocage)
    @wmfApi path /api/event /api/ping /api/zone

    handle_path /js/flow.js {
        rewrite * /w.js
        reverse_proxy https://wheremyflow.com {
            header_up Host wheremyflow.com
            header_down -Set-Cookie
        }
    }

    handle @wmfApi {
        reverse_proxy https://wheremyflow.com {
            header_up Host wheremyflow.com
            header_down -Set-Cookie
        }
    }
}

Puis :

caddy reload --config /etc/caddy/Caddyfile
Syntaxe Caddy 2.6+ : on utilise un matcher nommé (@wmfApi path …) pour appliquer handle à plusieurs chemins. La forme handle /a /b /c { … } n'est pas acceptée par le parser et fait échouer caddy validate.
Caddy injecte X-Forwarded-For et X-Real-IP automatiquement, c'est pourquoi on n'a pas besoin de les déclarer explicitement comme avec Nginx.

Recette 3 — Apache (mod_proxy)

Fonctionne sur : hébergement mutualisé OVH, Infomaniak, IONOS, et tout serveur Apache avec mod_proxy activé. Utile pour les sites WordPress sur cPanel sans accès root.

Souveraineté : neutre.

Dans votre .htaccess (à la racine du site) ou <VirtualHost> :

# wheremyflow — proxy 1st-party (anti-blocage)
SSLProxyEngine On

# Le script
RewriteEngine On
RewriteRule ^js/flow\.js$ https://wheremyflow.com/w.js [P,L]

# L'API
RewriteRule ^api/(event|ping|zone)$ https://wheremyflow.com/api/$1 [P,L]

# Préserver l'IP visiteur (setifempty pour ne pas écraser un XFF amont
# si vous êtes derrière un autre LB/reverse-proxy qui en pose déjà un)
ProxyPreserveHost Off
RequestHeader setifempty X-Forwarded-For "%{REMOTE_ADDR}s"
RequestHeader setifempty X-Real-IP       "%{REMOTE_ADDR}s"

# Ne jamais transmettre de cookie de session côté visiteur
Header always unset Set-Cookie

Modules à activer sur le serveur (typiquement déjà actifs sur les hébergeurs FR sérieux) : mod_proxy, mod_proxy_http, mod_ssl, mod_rewrite, mod_headers.

Sur OVH mutualisé, demandez l'activation à votre support si nécessaire — c'est gratuit et standard.


Recette 4 — Bunny.net Edge Scripting 🇸🇮 (CDN souverain UE)

Pour qui : sites à fort trafic qui veulent un CDN edge plus proche du visiteur (gain de latence + offload du serveur d'origine).

Souveraineté : 🇸🇮 Slovénie / Union européenne. Bunny.net (entreprise BunnyWay d.o.o., siège Maribor) est soumis au RGPD européen. Pas de Cloud Act US. Édité par une équipe slovène, opéré sur 119+ PoPs dont 30+ en UE.

Pricing : ~0,01 €/million de requêtes Edge Script + ~0,005 €/GB de bande passante CDN. Pour 1M pageviews/mois, comptez ~5 € total. Pas d'abonnement minimum, paiement à l'usage.

Étapes :

  1. Créer un compte sur bunny.net (carte bancaire, ~5 € de crédit initial gratuit).
  2. Créer une « Pull Zone » :
  • Onglet _CDN_ → bouton _Add Pull Zone_
  • Name : monsite-wmf (libre)
  • Origin URL : https://wheremyflow.com
  • Pricing tier : Standard
  • Pricing zones : décocher Asie + Amériques + Océanie, ne garder que Europe (souveraineté + coût réduit)
  1. Connecter votre domaine en CNAME :
  • Onglet _Hostnames_ → _Add Hostname_ → flow.monsite.com
  • Chez votre registrar DNS (Gandi, OVH, etc.) : créer un enregistrement CNAME flow.monsite.com → monsite-wmf.b-cdn.net
  • Attendez 5 min, retournez sur Bunny → cliquez _Generate Free SSL Certificate_ (Let's Encrypt automatique)
  1. Mapper le chemin :
  • Onglet _Edge Rules_ → _Add Edge Rule_
  • Action : _Override URL_
  • Match : Request URL contains "/js/flow.js"
  • Override URL : https://wheremyflow.com/w.js
  • Sauvegardez
  1. Snippet final :
<script defer src="https://flow.monsite.com/js/flow.js" data-site="monsite.com"></script>

Tous les /api/* passent automatiquement vers wheremyflow.com/api/* via la Pull Zone.

Note IP visiteur : Bunny ajoute par défaut X-Forwarded-For correctement. Vérifiez dans le dashboard wheremyflow > Audience > Géo que les pays remontent bien après 1-2 heures.

Recette 5 — Next.js / Nuxt rewrites

Pour qui : sites en stack moderne JavaScript déployés sur un hébergeur européen.

⚠️ Hébergement : ne déployez pas sur Vercel, Netlify, AWS, ou Fastly (entreprises américaines, soumises au Cloud Act). Préférez :

  • Clever Cloud 🇫🇷 (Paris)
  • Scaleway Serverless Functions 🇫🇷 (Paris/Amsterdam)
  • OVHcloud 🇫🇷
  • Render.com — région Frankfurt 🇩🇪 (à confirmer selon vos besoins légaux ; siège US donc moins safe que les précédents)
  • Auto-hébergement Docker sur un VPS UE

Next.js — dans next.config.js :

module.exports = {
  async rewrites() {
    return [
      {
        source: '/js/flow.js',
        destination: 'https://wheremyflow.com/w.js',
      },
      {
        source: '/api/event',
        destination: 'https://wheremyflow.com/api/event',
      },
      {
        source: '/api/ping',
        destination: 'https://wheremyflow.com/api/ping',
      },
      {
        source: '/api/zone',
        destination: 'https://wheremyflow.com/api/zone',
      },
    ];
  },
};

Nuxt 3 — dans nuxt.config.ts :

export default defineNuxtConfig({
  routeRules: {
    '/js/flow.js': { proxy: 'https://wheremyflow.com/w.js' },
    '/api/event': { proxy: 'https://wheremyflow.com/api/event' },
    '/api/ping': { proxy: 'https://wheremyflow.com/api/ping' },
    '/api/zone': { proxy: 'https://wheremyflow.com/api/zone' },
  },
});
Les rewrites Next/Nuxt préservent automatiquement X-Forwarded-For et la méthode HTTP. Les events POST passent correctement.

Hébergeurs et services explicitement déconseillés

Pour rester cohérent avec notre engagement souverain, n'utilisez pas :

| Service | Pays / siège | Pourquoi non | | ---------------------- | ---------------- | ---------------------------------------------------------------- | | Cloudflare Workers | 🇺🇸 San Francisco | Cloud Act US, obligation de coopérer avec gouvernement américain | | Vercel | 🇺🇸 San Francisco | Idem, infra principalement AWS US | | Netlify | 🇺🇸 San Francisco | Idem | | AWS CloudFront | 🇺🇸 Seattle | Cloud Act, FISA 702 | | Fastly | 🇺🇸 San Francisco | Idem | | Akamai | 🇺🇸 Cambridge MA | Idem |

Ces services peuvent être contraints par décision judiciaire américaine de transmettre les données proxifiées à l'administration US, même quand le serveur physique est situé en Europe (jurisprudence post-Schrems II / invalidation du Privacy Shield, juillet 2020). Pour un produit qui se vend comme « strictement souverain UE », cela ferait perdre votre argument commercial.


Vérifier que ça marche

  1. Le script se charge — ouvrez https://monsite.com/js/flow.js dans votre navigateur, vous devez voir le code minifié du tracker (commence par !function()...).
  2. Les events partent — ouvrez DevTools (F12) → onglet _Network_, cliquez sur une page de votre site. Vous devez voir une requête POST /api/event qui répond 204 No Content.
  3. La géolocalisation marche — connectez-vous au dashboard wheremyflow, attendez 1-2 minutes, et vérifiez l'onglet _Audience_ > _Géo_. Si tous les visiteurs remontent depuis le pays de votre serveur proxy au lieu de leur vrai pays, c'est que X-Forwarded-For n'est pas transmis. Revoir la conf du proxy.
  4. Le tracker dans l'onglet Intégration du dashboard — la sonde HTTP « Tester l'installation » détecte automatiquement le mode self-host et indique _« Proxy 1st-party détecté »_ dans le résultat.

Foire aux questions

Le proxy ralentit-il mon site ? Non, ou marginalement. Le tracker flow.js pèse 2.21 KB gzip (1.96 KB brotli) et reste en cache navigateur. Les events /api/* partent en sendBeacon non-bloquant, donc invisible pour le visiteur même si le proxy ajoute 50 ms de latence.

Et si mon proxy tombe en panne ? Les events sont perdus pendant la panne (pas de queue offline, par doctrine §25 TDDDG / RGPD minimisation). Le site continue de fonctionner normalement, c'est juste la mesure d'audience qui s'arrête. Comme tout autre service tiers en panne (Google Analytics, Plausible, etc.).

Puis-je proxifier seulement le script et pas l'API ? Oui, avec l'attribut data-api :

<script defer src="/js/flow.js" data-site="monsite.com" data-api="https://wheremyflow.com"></script>

Le script est servi en 1st-party (passe les bloqueurs basés sur le nom de fichier), mais les events partent vers wheremyflow.com directement (re-bloqués par les bloqueurs basés sur le domaine). C'est moins efficace que la recette complète et nous ne le recommandons pas — c'est documenté ici pour des cas particuliers.

Et si je veux changer de fournisseur d'analytics plus tard ? La doc proxy reste la même structure, vous changez juste les domaines cibles. Le snippet <script src="/js/flow.js" data-site="..."> est universel.


Besoin d'aide ?

  • 🛠️ Onglet _Intégration_ du dashboard → bouton _Tester l'installation_ (sonde HTTP automatique)
  • 📧 Contact DPO/support : voir l'onglet _Conformité_ du dashboard
  • 📚 Documentation complète : /docs