De tracker self-hosten (anti-blokkering)
Chrome 121+, uBlock Origin, Brave Shields, AdGuard en de meeste advertentieblokkeerders blokkeren standaard alle verzoeken naar domeinen van derden met het label "analytics", zelfs wanneer de dienst geen advertentietracking uitvoert (wat bij ons het geval is).
Zonder actie verliest u vandaag al 5 tot 20 % van de sessies, en dat aandeel zal stijgen naar 30–50 % binnen 12 tot 24 maanden, zodra Chrome _Tracking Protection_ toepast op alle normale sessies (niet alleen privévensters).
De oplossing: de tracker en de API serveren vanuit uw eigen domein. De browser ziet dan een "1st-party"-verzoek, niet te onderscheiden van een afbeelding of een stylesheet. Geen enkele blokkeerder blokkeert dat.
Deze pagina documenteert hoe u dit doet met first-party configuraties die passen bij een Europese infrastructuuraanpak. Kies host en uitvoeringsregio volgens uw behoeften rond compliance, performance en support.
Hoe het werkt — algemeen schema
┌──────────────────────────────────────────────────────────────────────────┐
│ │
│ VOOR (3rd-party, geblokkeerd) │
│ ────────────────────────────── │
│ │
│ browser ──► <script src="https://snorklee.com/w.js"> │
│ ❌ ERR_BLOCKED_BY_CLIENT │
│ │
│ browser ──► POST https://snorklee.com/api/event │
│ ❌ ERR_BLOCKED_BY_CLIENT │
│ │
└──────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│ │
│ NA (1st-party via uw proxy, nooit geblokkeerd) │
│ ───────────────────────────────────────────── │
│ │
│ browser ──► <script src="/js/flow.js"> op uwsite.com │
│ ✅ geserveerd door uw proxy vanuit snorklee.com │
│ │
│ browser ──► POST uwsite.com/api/event │
│ ✅ doorgestuurd door uw proxy naar snorklee.com │
│ │
└──────────────────────────────────────────────────────────────────────────┘
U proxiet 3 endpoints van uw domein naar snorklee.com:
| Pad op uw domein | Doel bij snorklee | Rol |
|---|---|---|
/js/flow.js | snorklee.com/w.js | Trackerscript |
/api/event | snorklee.com/api/event | Paginaweergaven + aangepaste events |
/api/ping | snorklee.com/api/ping | Heartbeat "live" elke 30 s |
/api/zone | snorklee.com/api/zone | Scrollzones (leeraandacht) |
Het snippet dat u in uw <head> plakt, wordt:
<script defer src="/js/flow.js" data-site="uwsite.com"></script>
Alle paden zijn 1st-party; vanuit de browser verlaat niets het domein. Aan de serverzijde legt uw proxy transparant de verbinding met snorklee.com.
Belangrijk — bewaar het IP-adres van de bezoeker: uw proxy moet de header X-Forwarded-For correct doorgeven, anders koppelt de geolocatie van snorklee het IP-adres van uw proxy aan de bezoeker in plaats van diens werkelijke adres. Elk recept hieronder bevat dit expliciet.
Recept 1 — Nginx (de meest universele)
Werkt op: elke Linux-VPS (OVH, Scaleway, Hetzner, Clever Cloud met Nginx-runtime, IONOS, Infomaniak, enz.).
Soevereiniteit: neutraal (afhankelijk van uw hostingprovider; kies EU).
Voeg dit blok toe binnen het server { ... }-blok dat uw site serveert (doorgaans /etc/nginx/sites-available/uwsite.conf):
# snorklee — 1st-party proxy (anti-blokkering)
location = /js/flow.js {
proxy_pass https://snorklee.com/w.js;
proxy_set_header Host snorklee.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://snorklee.com$request_uri;
proxy_set_header Host snorklee.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;
}
Test en herlaad vervolgens:
sudo nginx -t && sudo systemctl reload nginx
Verificatie: open https://uwsite.com/js/flow.js in uw browser — u zou de geminimaliseerde trackercode moeten zien. Bij een 502-fout controleert u of proxy_ssl_server_name on; aanwezig is (verplicht voor SNI naar snorklee.com).
Recept 2 — Caddy (de eenvoudigste)
Werkt op: elke server waarop Caddy draait (inclusief automatische TLS).
Soevereiniteit: neutraal (afhankelijk van uw hostingprovider).
In uw Caddyfile, binnen het blok van uw site:
uwsite.com {
# ... uw bestaande configuratie ...
# snorklee — 1st-party proxy (anti-blokkering)
@snorkleeApi path /api/event /api/ping /api/zone
handle_path /js/flow.js {
rewrite * /w.js
reverse_proxy https://snorklee.com {
header_up Host snorklee.com
header_down -Set-Cookie
}
}
handle @snorkleeApi {
reverse_proxy https://snorklee.com {
header_up Host snorklee.com
header_down -Set-Cookie
}
}
}
Vervolgens:
caddy reload --config /etc/caddy/Caddyfile
Caddy 2.6+-syntaxis: gebruik een benoemde matcher (@snorkleeApi path …) omhandleop meerdere paden toe te passen. De vormhandle /a /b /c { … }wordt niet geaccepteerd door de parser en doetcaddy validatemislukken.
Caddy injecteertX-Forwarded-ForenX-Real-IPautomatisch — u hoeft deze niet expliciet te declareren zoals bij Nginx.
Recept 3 — Apache (mod_proxy)
Werkt op: gedeelde hosting van OVH, Infomaniak, IONOS en elke Apache-server met mod_proxy ingeschakeld. Handig voor WordPress-sites op cPanel zonder root-toegang.
Soevereiniteit: neutraal.
In uw .htaccess (in de root van de site) of <VirtualHost>:
# snorklee — 1st-party proxy (anti-blokkering)
SSLProxyEngine On
# Het script
RewriteEngine On
RewriteRule ^js/flow\.js$ https://snorklee.com/w.js [P,L]
# De API
RewriteRule ^api/(event|ping|zone)$ https://snorklee.com/api/$1 [P,L]
# Bewaar het IP-adres van de bezoeker (setifempty overschrijft geen upstream XFF
# als u achter een andere LB/reverse-proxy zit die er al een instuurt)
ProxyPreserveHost Off
RequestHeader setifempty X-Forwarded-For "%{REMOTE_ADDR}s"
RequestHeader setifempty X-Real-IP "%{REMOTE_ADDR}s"
# Nooit een sessiecookie aan de bezoekerskant doorsturen
Header always unset Set-Cookie
Te activeren modules op de server (doorgaans al actief bij serieuze EU-hosters): mod_proxy, mod_proxy_http, mod_ssl, mod_rewrite, mod_headers.
Bij OVH gedeelde hosting kunt u activering via de support aanvragen — dit is gratis en standaard.
Recept 4 — Bunny.net Edge Scripting
Voor wie: sites met veel verkeer die een CDN-edge dichter bij de bezoeker willen (lagere latentie + minder belasting van de oorsprongsserver).
Europese aanwezigheid: Bunny.net wordt beheerd door BunnyWay d.o.o. in Slovenië. Als u de routing dicht bij Europa wilt houden, beperk de pricing zones dan tijdens de configuratie tot Europe.
Prijzen: ~€ 0,01 per miljoen Edge Script-verzoeken + ~€ 0,005 per GB CDN-bandbreedte. Voor 1 M paginaweergaven per maand rekent u op ~€ 5 totaal. Geen minimumabonnement, betaal per gebruik.
Stappen:
- Maak een account aan op bunny.net (creditcard, ~€ 5 gratis startkrediet).
- Maak een "Pull Zone" aan:
- Tabblad _CDN_ → knop _Add Pull Zone_
- Name:
mijnsite-snorklee(vrije keuze) - Origin URL:
https://snorklee.com - Pricing tier: Standard
- Pricing zones: u kunt alleen Europe aanhouden als u routing en kosten tot die zone wilt beperken
- Koppel uw domein via CNAME:
- Tabblad _Hostnames_ → _Add Hostname_ →
flow.uwsite.com - Bij uw DNS-registrar (Gandi, OVH, enz.): maak een
CNAME flow.uwsite.com → mijnsite-snorklee.b-cdn.netaan - Wacht 5 minuten, keer terug naar Bunny → klik op _Generate Free SSL Certificate_ (automatisch Let's Encrypt)
- Wijs het pad toe:
- Tabblad _Edge Rules_ → _Add Edge Rule_
- Action: _Override URL_
- Match:
Request URL contains "/js/flow.js" - Override URL:
https://snorklee.com/w.js - Sla op
- Definitief snippet:
<script defer src="https://flow.uwsite.com/js/flow.js" data-site="uwsite.com"></script>
Alle /api/*-paden worden automatisch doorgestuurd naar snorklee.com/api/* via de Pull Zone.
Opmerking IP-adres: Bunny voegt standaard X-Forwarded-For correct in. Controleer in het snorklee-dashboard, tabblad Dashboard, sectie Publiek, kaart Landen, of de landen correct oplossen na 1–2 uur.
Recept 5 — Next.js / Nuxt rewrites
Voor wie: sites met een moderne JavaScript-stack waarvan de host rewrites of serverroutes ondersteunt.
Hosting: controleer dat uw platform de nuttige headers behoudt (X-Forwarded-For, HTTP-methode, User-Agent, Accept-Language) en dat de gekozen uitvoeringsregio past bij uw privacy- en performancebehoeften.
Mogelijke opties zijn klassieke Node/SSR-hosting, serverless met expliciete regio, een Docker-container of een frontendplatform met server-side rewrites.
Next.js — in next.config.js:
module.exports = {
async rewrites() {
return [
{
source: '/js/flow.js',
destination: 'https://snorklee.com/w.js',
},
{
source: '/api/event',
destination: 'https://snorklee.com/api/event',
},
{
source: '/api/ping',
destination: 'https://snorklee.com/api/ping',
},
{
source: '/api/zone',
destination: 'https://snorklee.com/api/zone',
},
];
},
};
Nuxt 3 — in nuxt.config.ts:
export default defineNuxtConfig({
routeRules: {
'/js/flow.js': { proxy: 'https://snorklee.com/w.js' },
'/api/event': { proxy: 'https://snorklee.com/api/event' },
'/api/ping': { proxy: 'https://snorklee.com/api/ping' },
'/api/zone': { proxy: 'https://snorklee.com/api/zone' },
},
});
Next/Nuxt rewrites bewaren X-Forwarded-For en de HTTP-methode automatisch. POST-events worden correct doorgestuurd.
Uw host kiezen
De first-party proxy werkt met veel hosters. Controleer voordat u een platform kiest vooral:
- de uitvoeringsregio die de proxy werkelijk gebruikt;
- de bewaartermijn van logs bij de hoster;
- correcte doorgifte van
X-Forwarded-For; - de mogelijkheid om onnodige cookies of headers te verwijderen;
- de contractuele toezeggingen die u nodig hebt voor uw eigen privacybeleid.
Controleren of het werkt
- Het script wordt geladen — open
https://uwsite.com/js/flow.jsin uw browser; u zou de geminimaliseerde trackercode moeten zien (begint met!function()...). - De events worden verzonden — open DevTools (F12) → tabblad _Network_, klik op een pagina van uw site. U zou een verzoek
POST /api/eventmoeten zien met de respons204 No Content. - De geolocatie werkt — log in op het snorklee-dashboard, wacht 1–2 minuten en controleer het tabblad Dashboard, sectie Publiek, kaart Landen. Als alle bezoekers terugkomen vanuit het land van uw proxyserver in plaats van hun werkelijke land, wordt
X-Forwarded-Forniet doorgestuurd. Controleer de proxyconfiguratie opnieuw. - De tracker in het tabblad Integratie van het dashboard — de HTTP-sonde "Installatie testen" detecteert de self-hostmodus automatisch en toont _"1st-party proxy gedetecteerd"_ in het resultaat.
Veelgestelde vragen
Vertraagt de proxy mijn site? Nee, of marginaal. De tracker flow.js weegt ≈ 2 KB gzip en blijft gecacht in de browser. Events worden verzonden via de niet-blokkerende sendBeacon, zodat ze voor de bezoeker onzichtbaar zijn, zelfs als de proxy 50 ms latentie toevoegt.
Wat als mijn proxy uitvalt? Events gaan verloren tijdens de storing (geen offline wachtrij, conform §25 TDDDG / AVG-minimalisatie). De site werkt normaal door — alleen de publieksmeting stopt. Net als bij elke andere externe dienst die uitvalt (Google Analytics, Plausible, enz.).
Kan ik alleen het script proxyen en niet de API? Ja, met het attribuut data-api:
<script defer src="/js/flow.js" data-site="uwsite.com" data-api="https://snorklee.com"></script>
Het script wordt als 1st-party geserveerd (passeert blokkeerders op bestandsnaam), maar events gaan rechtstreeks naar snorklee.com (opnieuw geblokkeerd door domeingebaseerde blokkeerders). Dit is minder effectief dan het volledige recept en wij raden het niet aan — het staat hier gedocumenteerd voor bijzondere gevallen.
Wat als ik later van analytics-aanbieder wil wisselen? De proxystructuur blijft gelijk; u verandert alleen de doeldomeinen. Het snippet <script src="/js/flow.js" data-site="..."> is universeel.
Hulp nodig?
- 🛠️ Tabblad _Integratie_ van het dashboard → knop _Installatie testen_ (automatische HTTP-sonde)
- 📧 Contact gegevensbescherming/support: zie het tabblad _Conformiteit_ van het dashboard
- 📚 Volledige documentatie: /docs