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

Autoalojar el tracker (anti-bloqueo)

Chrome 121+, uBlock Origin, Brave Shields, AdGuard y la mayoría de bloqueadores de anuncios bloquean por defecto cualquier solicitud hacia un dominio de terceros etiquetado como "analytics", aunque el servicio no haga ningún seguimiento publicitario (que es nuestro caso).

Sin hacer nada, pierdes hoy del 5 al 20 % de las sesiones, y esa proporción subirá al 30-50 % en 12-24 meses cuando Chrome aplique la _Tracking Protection_ a todas las sesiones normales (no solo la navegación privada).

La solución: servir el tracker y la API desde tu propio dominio. El navegador ve entonces una solicitud "1st-party" indistinguible de una imagen o una hoja de estilos. Ningún bloqueador bloquea eso.

Esta página documenta cómo hacerlo con configuraciones first-party compatibles con un enfoque de infraestructura europea. Elige el alojamiento y la región de ejecución según tus necesidades de cumplimiento, rendimiento y soporte.


Cómo funciona — esquema general

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

┌──────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│   DESPUÉS (1st-party vía tu proxy, nunca bloqueado)                      │
│   ─────────────────────────────────────────────                          │
│                                                                          │
│   navegador ──► <script src="/js/flow.js"> en misiitio.com               │
│                 ✅ servido por tu proxy desde snorklee.com            │
│                                                                          │
│   navegador ──► POST misitio.com/api/event                               │
│                 ✅ retransmitido por tu proxy hacia snorklee.com      │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘

Proxificas 3 endpoints desde tu dominio hacia snorklee.com:

Ruta en tu dominioDestino en snorkleeFunción
/js/flow.jssnorklee.com/w.jsScript del tracker
/api/eventsnorklee.com/api/eventPageviews + eventos personalizados
/api/pingsnorklee.com/api/pingHeartbeat "live" cada 30 s
/api/zonesnorklee.com/api/zoneZonas de scroll (lectura)

El snippet que pegas en tu <head> se convierte en:

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

Todas las rutas son 1st-party; ninguna sale hacia un dominio de terceros desde el navegador. En el servidor, tu proxy hace el puente con snorklee.com de forma transparente.

Importante — preservar la IP del visitante: tu proxy debe transmitir el header X-Forwarded-For correctamente, de lo contrario la geolocalización de snorklee resolverá la IP de tu proxy en lugar de la del visitante. Cada receta a continuación lo incluye de forma explícita.

Receta 1 — Nginx (la más universal)

Funciona en: cualquier VPS Linux (OVH, Scaleway, Hetzner, Clever Cloud con runtime Nginx, IONOS, Infomaniak, etc.).

Soberanía: neutra (depende de tu proveedor de alojamiento; elige UE).

Añade este bloque en tu archivo de configuración Nginx, dentro del server { ... } que sirve tu sitio (normalmente /etc/nginx/sites-available/misitio.conf):

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

Luego prueba y recarga:

sudo nginx -t && sudo systemctl reload nginx

Verificación: abre https://misitio.com/js/flow.js en tu navegador — debes ver el código minificado del tracker. Si aparece el error 502, comprueba que proxy_ssl_server_name on; esté presente (obligatorio para el SNI hacia snorklee.com).


Receta 2 — Caddy (la más sencilla)

Funciona en: cualquier servidor donde corra Caddy (TLS automático incluido).

Soberanía: neutra (depende de tu proveedor de alojamiento).

En tu Caddyfile, dentro del bloque de tu sitio:

misitio.com {
    # ... tu configuración existente ...

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

Luego:

caddy reload --config /etc/caddy/Caddyfile
Sintaxis Caddy 2.6+: se usa un matcher con nombre (@snorkleeApi path …) para aplicar handle a varias rutas. La forma handle /a /b /c { … } no es aceptada por el parser y hace fallar caddy validate.
Caddy inyecta X-Forwarded-For y X-Real-IP automáticamente, por lo que no es necesario declararlos explícitamente como en Nginx.

Receta 3 — Apache (mod_proxy)

Funciona en: alojamiento compartido OVH, Infomaniak, IONOS y cualquier servidor Apache con mod_proxy activado. Útil para sitios WordPress en cPanel sin acceso root.

Soberanía: neutra.

En tu .htaccess (en la raíz del sitio) o <VirtualHost>:

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

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

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

# Preservar la IP del visitante (setifempty para no sobreescribir un XFF previo
# si estás detrás de otro LB/reverse-proxy que ya lo añade)
ProxyPreserveHost Off
RequestHeader setifempty X-Forwarded-For "%{REMOTE_ADDR}s"
RequestHeader setifempty X-Real-IP       "%{REMOTE_ADDR}s"

# No transmitir nunca cookies de sesión al visitante
Header always unset Set-Cookie

Módulos a activar en el servidor (normalmente ya activos en alojadores FR serios): mod_proxy, mod_proxy_http, mod_ssl, mod_rewrite, mod_headers.

En OVH compartido, solicita la activación al soporte si es necesario — es gratuito y estándar.


Receta 4 — Bunny.net Edge Scripting

Para quién: sitios de alto tráfico que quieren un CDN edge más cercano al visitante (ganancia de latencia + descarga del servidor de origen).

Presencia europea: Bunny.net está operado por BunnyWay d.o.o. en Eslovenia. Si quieres mantener el enrutamiento cerca de Europa, limita las zonas de pricing a Europe durante la configuración.

Precios: ~0,01 €/millón de solicitudes Edge Script + ~0,005 €/GB de ancho de banda CDN. Para 1M pageviews/mes, cuenta ~5 € en total. Sin suscripción mínima, pago por uso.

Pasos:

  1. Crear una cuenta en bunny.net (tarjeta bancaria, ~5 € de crédito inicial gratuito).
  2. Crear una "Pull Zone":
  • Pestaña _CDN_ → botón _Add Pull Zone_
  • Name: misitio-snorklee (libre)
  • Origin URL: https://snorklee.com
  • Pricing tier: Standard
  • Pricing zones: puedes mantener solo Europe si quieres limitar el enrutamiento y los costes a esa zona
  1. Conectar tu dominio por CNAME:
  • Pestaña _Hostnames_ → _Add Hostname_ → flow.misitio.com
  • En tu registrar DNS (Gandi, OVH, etc.): crear un registro CNAME flow.misitio.com → misitio-snorklee.b-cdn.net
  • Esperar 5 min, volver a Bunny → clic en _Generate Free SSL Certificate_ (Let's Encrypt automático)
  1. Mapear la ruta:
  • Pestaña _Edge Rules_ → _Add Edge Rule_
  • Action: _Override URL_
  • Match: Request URL contains "/js/flow.js"
  • Override URL: https://snorklee.com/w.js
  • Guardar
  1. Snippet final:
<script defer src="https://flow.misitio.com/js/flow.js" data-site="misitio.com"></script>

Todas las rutas /api/* pasan automáticamente hacia snorklee.com/api/* a través de la Pull Zone.

Nota IP visitante: Bunny añade X-Forwarded-For correctamente por defecto. Comprueba en el panel de snorklee, pestaña Panel, sección Audiencia, tarjeta Países, que los países aparecen correctamente al cabo de 1-2 horas.

Receta 5 — Next.js / Nuxt rewrites

Para quién: sitios con stack JavaScript moderno cuyo alojamiento admite rewrites o rutas de servidor.

Alojamiento: comprueba que tu plataforma conserva los headers útiles (X-Forwarded-For, método HTTP, User-Agent, Accept-Language) y que la región de ejecución elegida corresponde a tus necesidades de privacidad y rendimiento.

Opciones posibles: alojamiento Node/SSR clásico, serverless con región explícita, contenedor Docker o plataforma frontend que exponga rewrites del lado servidor.

Next.js — en 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 — en 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' },
  },
});
Los rewrites de Next/Nuxt preservan automáticamente X-Forwarded-For y el método HTTP. Los eventos POST pasan correctamente.

Elegir tu alojamiento

El proxy first-party funciona con muchos alojamientos. Antes de elegir una plataforma, comprueba sobre todo:

  • la región de ejecución que utiliza realmente el proxy;
  • el periodo de conservación de logs del alojamiento;
  • la transmisión correcta de X-Forwarded-For;
  • la posibilidad de retirar cookies o headers innecesarios;
  • los compromisos contractuales que necesitas para tu propia política de privacidad.

Verificar que funciona

  1. El script se carga — abre https://misitio.com/js/flow.js en tu navegador; debes ver el código minificado del tracker (comienza por !function()...).
  2. Los eventos se envían — abre DevTools (F12) → pestaña _Network_, navega por tu sitio. Debes ver una solicitud POST /api/event que responde 204 No Content.
  3. La geolocalización funciona — conéctate al panel de snorklee, espera 1-2 minutos y comprueba la pestaña _Panel_, sección Audiencia, tarjeta Países. Si todos los visitantes aparecen desde el país de tu servidor proxy en lugar del suyo real, es que X-Forwarded-For no se está transmitiendo. Revisa la configuración del proxy.
  4. El tracker en la pestaña Integración del panel — la sonda HTTP "Probar instalación" detecta automáticamente el modo self-host e indica _"Proxy 1st-party detectado"_ en el resultado.

Preguntas frecuentes

¿El proxy ralentiza mi sitio? No, o de forma marginal. El tracker flow.js pesa ≈ 2 KB gzip y permanece en caché del navegador. Los eventos /api/* se envían mediante sendBeacon no bloqueante, por lo que son invisibles para el visitante aunque el proxy añada 50 ms de latencia.

¿Y si mi proxy falla? Los eventos se pierden durante la avería (sin cola offline, por doctrina §25 TDDDG / RGPD minimización). El sitio sigue funcionando con normalidad; solo se detiene la medición de audiencia. Como cualquier otro servicio de terceros en fallo (Google Analytics, Plausible, etc.).

¿Puedo proxificar solo el script y no la API? Sí, con el atributo data-api:

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

El script se sirve en 1st-party (pasa los bloqueadores basados en el nombre de archivo), pero los eventos van directamente a snorklee.com (re-bloqueados por los bloqueadores basados en dominio). Es menos eficaz que la receta completa y no lo recomendamos — se documenta aquí para casos particulares.

¿Y si quiero cambiar de proveedor de analytics más adelante? La estructura del proxy permanece igual; solo cambias los dominios de destino. El snippet <script src="/js/flow.js" data-site="..."> es universal.


¿Necesitas ayuda?

  • 🛠️ Pestaña _Integración_ del panel → botón _Probar instalación_ (sonda HTTP automática)
  • 📧 Contacto de protección de datos/soporte: ver la pestaña _Conformidad_ del panel
  • 📚 Documentación completa: /docs