Aller au contenu
snorklee
Fonctionnalités Trafic IA Tarifs Manifeste Aide Audit Contact Connexion Démarrer gratuitement

Self-host del tracker (anti-blocco)

Chrome 121+, uBlock Origin, Brave Shields, AdGuard e la maggior parte dei blocchi pubblicitari bloccano per impostazione predefinita qualsiasi richiesta verso un dominio di terze parti etichettato come "analytics", anche quando il servizio non effettua alcun tracking pubblicitario (come nel nostro caso).

Senza intervento, perdi oggi dal 5 al 20% delle sessioni, e questa quota salirà al 30-50% nei prossimi 12-24 mesi quando Chrome applicherà il _Tracking Protection_ a tutte le sessioni normali (non solo alla navigazione privata).

La soluzione: servire il tracker e l'API dal tuo dominio. Il browser vede allora una richiesta "1st-party" indistinguibile da una chiamata a un'immagine o a un foglio di stile. Nessun blocco blocca questo.

Questa pagina documenta come farlo con configurazioni first-party compatibili con un approccio di infrastruttura europea. Scegli hosting e regione di esecuzione in base alle tue esigenze di conformità, performance e supporto.


Come funziona — schema generale

┌──────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│   PRIMA (3rd-party, bloccato)                                            │
│   ──────────────────────────                                             │
│                                                                          │
│   navigatore ──► <script src="https://snorklee.com/w.js">             │
│                  ❌ ERR_BLOCKED_BY_CLIENT                                 │
│                                                                          │
│   navigatore ──► POST https://snorklee.com/api/event                  │
│                  ❌ ERR_BLOCKED_BY_CLIENT                                 │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│   DOPO (1st-party via il tuo proxy, mai bloccato)                        │
│   ────────────────────────────────────────────                           │
│                                                                          │
│   navigatore ──► <script src="/js/flow.js"> su miosito.com               │
│                  ✅ servito dal tuo proxy da snorklee.com             │
│                                                                          │
│   navigatore ──► POST miosito.com/api/event                              │
│                  ✅ inoltrato dal tuo proxy verso snorklee.com        │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘

Stai facendo il proxy di 3 endpoint dal tuo dominio verso snorklee.com:

Percorso sul tuo dominioDestinazione su snorkleeRuolo
/js/flow.jssnorklee.com/w.jsScript del tracker
/api/eventsnorklee.com/api/eventPageview + eventi personalizzati
/api/pingsnorklee.com/api/pingHeartbeat "live" ogni 30 s
/api/zonesnorklee.com/api/zoneZone di scorrimento (lettura)

Lo snippet da incollare nell'<head> diventa:

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

Tutti i percorsi sono in 1st-party, nessuno esce verso un dominio di terze parti dal browser. Lato server, il tuo proxy fa da ponte con snorklee.com in modo trasparente.

Importante — preservazione dell'IP visitatore: il tuo proxy deve trasmettere l'header X-Forwarded-For correttamente, altrimenti la geolocalizzazione lato snorklee ricade sull'IP del tuo proxy invece di quello del visitatore. Ogni ricetta qui sotto lo include esplicitamente.

Ricetta 1 — Nginx (la più universale)

Funziona su: qualsiasi VPS Linux (OVH, Scaleway, Hetzner, Clever Cloud con runtime Nginx, IONOS, Infomaniak, ecc.).

Sovranità: neutrale (dipende dal tuo provider; scegli UE).

Aggiungi questo blocco nel tuo file di configurazione Nginx, all'interno del server { ... } che serve il tuo sito (tipicamente /etc/nginx/sites-available/miosito.conf):

# snorklee — proxy 1st-party (anti-blocco)
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;
}

Poi testa e ricarica:

sudo nginx -t && sudo systemctl reload nginx

Verifica: dal tuo browser, apri https://miosito.com/js/flow.js — dovresti vedere il codice del tracker minificato. Se ottieni un errore 502, verifica che proxy_ssl_server_name on; sia presente (obbligatorio per il SNI verso snorklee.com).


Ricetta 2 — Caddy (la più semplice)

Funziona su: qualsiasi server dove Caddy è in esecuzione (auto-TLS incluso).

Sovranità: neutrale (dipende dal tuo provider).

Nel tuo Caddyfile, all'interno del blocco del tuo sito:

miosito.com {
    # ... la tua configurazione esistente ...

    # snorklee — proxy 1st-party (anti-blocco)
    @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
        }
    }
}

Poi:

caddy reload --config /etc/caddy/Caddyfile
Sintassi Caddy 2.6+: si usa un matcher con nome (@snorkleeApi path …) per applicare handle a più percorsi. La forma handle /a /b /c { … } non è accettata dal parser e fa fallire caddy validate.
Caddy inietta X-Forwarded-For e X-Real-IP automaticamente, quindi non è necessario dichiararli esplicitamente come con Nginx.

Ricetta 3 — Apache (mod_proxy)

Funziona su: hosting condiviso OVH, Infomaniak, IONOS, e qualsiasi server Apache con mod_proxy attivato. Utile per siti WordPress su cPanel senza accesso root.

Sovranità: neutrale.

Nel tuo .htaccess (alla radice del sito) o <VirtualHost>:

# snorklee — proxy 1st-party (anti-blocco)
SSLProxyEngine On

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

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

# Preservare l'IP visitatore (setifempty per non sovrascrivere un XFF a monte
# se sei dietro un altro LB/reverse-proxy che ne imposta già uno)
ProxyPreserveHost Off
RequestHeader setifempty X-Forwarded-For "%{REMOTE_ADDR}s"
RequestHeader setifempty X-Real-IP       "%{REMOTE_ADDR}s"

# Non trasmettere mai cookie di sessione lato visitatore
Header always unset Set-Cookie

Moduli da attivare sul server (tipicamente già attivi sugli host FR seri): mod_proxy, mod_proxy_http, mod_ssl, mod_rewrite, mod_headers.

Su OVH condiviso, richiedi l'attivazione al supporto se necessario — è gratuita e standard.


Ricetta 4 — Bunny.net Edge Scripting

Per chi: siti ad alto traffico che vogliono un CDN edge più vicino al visitatore (guadagno di latenza + scarico del server di origine).

Presenza europea: Bunny.net è gestito da BunnyWay d.o.o. in Slovenia. Se vuoi mantenere il routing vicino all'Europa, limita le zone di pricing a Europe durante la configurazione.

Prezzi: ~0,01 €/milione di richieste Edge Script + ~0,005 €/GB di banda CDN. Per 1M pageview/mese, conta ~5 € in totale. Nessun abbonamento minimo, pagamento a consumo.

Passaggi:

  1. Crea un account su bunny.net (carta di credito, ~5 € di credito iniziale gratuito).
  2. Crea una "Pull Zone":
  • Scheda _CDN_ → pulsante _Add Pull Zone_
  • Name: miosito-snorklee (libero)
  • Origin URL: https://snorklee.com
  • Pricing tier: Standard
  • Pricing zones: puoi lasciare solo Europe se vuoi limitare routing e costi a quella zona
  1. Collega il tuo dominio via CNAME:
  • Scheda _Hostnames_ → _Add Hostname_ → flow.miosito.com
  • Presso il tuo registrar DNS (Gandi, OVH, ecc.): crea un record CNAME flow.miosito.com → miosito-snorklee.b-cdn.net
  • Attendi 5 min, torna su Bunny → clicca _Generate Free SSL Certificate_ (Let's Encrypt automatico)
  1. Mappa il percorso:
  • Scheda _Edge Rules_ → _Add Edge Rule_
  • Action: _Override URL_
  • Match: Request URL contains "/js/flow.js"
  • Override URL: https://snorklee.com/w.js
  • Salva
  1. Snippet finale:
<script defer src="https://flow.miosito.com/js/flow.js" data-site="miosito.com"></script>

Tutti i percorsi /api/* passano automaticamente verso snorklee.com/api/* tramite la Pull Zone.

Nota IP visitatore: Bunny aggiunge X-Forwarded-For correttamente per impostazione predefinita. Verifica nella scheda Dashboard, sezione Pubblico, card Paesi, che i paesi vengano rilevati correttamente dopo 1-2 ore.

Ricetta 5 — Next.js / Nuxt rewrites

Per chi: siti con stack JavaScript moderno il cui hosting supporta rewrite o route server.

Hosting: verifica che la piattaforma conservi gli header utili (X-Forwarded-For, metodo HTTP, User-Agent, Accept-Language) e che la regione di esecuzione scelta corrisponda alle tue esigenze di privacy e performance.

Opzioni possibili: hosting Node/SSR classico, serverless con regione esplicita, container Docker o piattaforma frontend che espone rewrite lato server.

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' },
  },
});
I rewrites Next/Nuxt preservano automaticamente X-Forwarded-For e il metodo HTTP. Gli eventi POST vengono trasmessi correttamente.

Scegliere l'hosting

Il proxy first-party funziona con molti hosting. Prima di scegliere una piattaforma, verifica soprattutto:

  • la regione di esecuzione realmente usata dal proxy;
  • il periodo di conservazione dei log lato hosting;
  • la trasmissione corretta di X-Forwarded-For;
  • la possibilità di rimuovere cookie o header inutili;
  • gli impegni contrattuali necessari per la tua policy privacy.

Verifica che funzioni

  1. Lo script si carica — apri https://miosito.com/js/flow.js nel tuo browser, dovresti vedere il codice del tracker minificato (inizia con !function()...).
  2. Gli eventi partono — apri DevTools (F12) → scheda _Network_, naviga nel tuo sito. Dovresti vedere una richiesta POST /api/event che risponde 204 No Content.
  3. La geolocalizzazione funziona — connettiti alla dashboard snorklee, attendi 1-2 minuti e verifica la card _Paesi_ nella scheda _Dashboard_ (sezione Pubblico). Se tutti i visitatori appaiono dal paese del tuo server proxy invece del loro vero paese, X-Forwarded-For non viene trasmesso. Rivedi la configurazione del proxy.
  4. Il tracker nella scheda Integrazione della dashboard — la sonda HTTP "Testa l'installazione" rileva automaticamente la modalità self-host e mostra _"Proxy 1st-party rilevato"_ nel risultato.

Domande frequenti

Il proxy rallenta il mio sito? No, o in modo marginale. Il tracker flow.js pesa ≈ 2 KB gzip e rimane nella cache del browser. Gli eventi /api/* partono tramite sendBeacon non bloccante, quindi invisibili al visitatore anche se il proxy aggiunge 50 ms di latenza.

E se il mio proxy va in panne? Gli eventi vengono persi durante l'interruzione (nessuna coda offline, per dottrina §25 TDDDG / GDPR minimizzazione). Il sito continua a funzionare normalmente, si ferma solo la misurazione dell'audience. Come qualsiasi altro servizio di terze parti in panne (Google Analytics, Plausible, ecc.).

Posso fare il proxy solo dello script e non dell'API? Sì, con l'attributo data-api:

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

Lo script viene servito in 1st-party (supera i blocchi basati sul nome del file), ma gli eventi partono direttamente verso snorklee.com (nuovamente bloccati dai blocchi basati sul dominio). È meno efficace della ricetta completa e non lo raccomandiamo — è documentato qui per casi particolari.

E se voglio cambiare provider di analytics in seguito? La struttura del proxy rimane la stessa, cambi solo i domini di destinazione. Lo snippet <script src="/js/flow.js" data-site="..."> è universale.


Hai bisogno di aiuto?

  • 🛠️ Scheda _Integrazione_ della dashboard → pulsante _Testa l'installazione_ (sonda HTTP automatica)
  • 📧 Contatto protezione dati/supporto: vedi la scheda _Conformità_ della dashboard
  • 📚 Documentazione completa: /docs