04 · Seguimiento
Sirve el script desde tu propio dominio
Dos rutas de tu sitio, reenviadas a Tally, hacen que el script y sus eventos sean de tu propio dominio.
01Por qué servirlo tú mismo
Los bloqueadores de anuncios bloquean la analítica por la dirección desde la que se carga. Servidos desde tu propio dominio, el script y sus eventos no están en sus listas. La cookie de visitante no depende de ello: el script la pone en el dominio de tu página en cualquier caso.
02Dos rutas que reenviar
| En tu sitio | Reenvía a |
|---|---|
/js/script.js | https://t.tallybyoutpost.com/script.js |
/api/event | https://t.tallybyoutpost.com/api/event |
Después, carga el script desde tu sitio. Envía los eventos a /api/event en su propia dirección, así que nada más cambia:
<script defer data-site="k3xq2mfa7twp" src="/js/script.js"></script>Si tu sitio ya tiene un /api/event, reenvía otra ruta y apunta el script a ella con data-api="/your/path".
03Lo que debe hacer todo proxy
- Deja pasar el user agent: es lo que sirve para filtrar los bots.
- Reenvía la dirección IP del visitante en
X-Forwarded-For: sirve para averiguar su ciudad (y, en un sitio sin cookies, para contarlo), y después se descarta. Un servidor que reenvía a sus visitantes recibe el cupo de eventos más amplio de un proxy, para que no compartan el de un solo navegador. - No reenvíes las cookies: no se leen.
- Si quieres, responde al navegador de inmediato (
202): el script ignora todas las respuestas.
04En tu servidor
// next.config.js
module.exports = {
async rewrites() {
return [
{ source: '/js/script.js', destination: 'https://t.tallybyoutpost.com/script.js' },
{ source: '/api/event', destination: 'https://t.tallybyoutpost.com/api/event' },
];
},
};
En Vercel, el rewrite lleva X-Forwarded-For. Una ruta /api/event propia de la app tiene prioridad: usa otra ruta y data-api.
{
"rewrites": [
{ "source": "/js/script.js", "destination": "https://t.tallybyoutpost.com/script.js" },
{ "source": "/api/event", "destination": "https://t.tallybyoutpost.com/api/event" }
]
}
vercel.json, para un sitio en Vercel sin Next.js.
# netlify.toml
[[redirects]]
from = "/js/script.js"
to = "https://t.tallybyoutpost.com/script.js"
status = 200
force = true
[[redirects]]
from = "/api/event"
to = "https://t.tallybyoutpost.com/api/event"
status = 200
force = true
location = /js/script.js {
proxy_pass https://t.tallybyoutpost.com/script.js;
proxy_set_header Host t.tallybyoutpost.com;
proxy_ssl_server_name on;
}
location = /api/event {
proxy_pass https://t.tallybyoutpost.com/api/event;
proxy_set_header Host t.tallybyoutpost.com;
proxy_ssl_server_name on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie "";
}
yoursite.com {
handle /js/script.js {
rewrite * /script.js
reverse_proxy https://t.tallybyoutpost.com {
header_up Host {upstream_hostport}
}
}
handle /api/event {
reverse_proxy https://t.tallybyoutpost.com {
header_up Host {upstream_hostport}
header_up -Cookie
}
}
# … the site's own handlers
}
Caddy pone X-Forwarded-For por sí solo.
// Routed on yoursite.com/js/script.js and yoursite.com/api/event.
const UPSTREAM = {
'/js/script.js': 'https://t.tallybyoutpost.com/script.js',
'/api/event': 'https://t.tallybyoutpost.com/api/event',
};
export default {
async fetch(request) {
const upstream = UPSTREAM[new URL(request.url).pathname];
if (!upstream) return fetch(request);
const headers = new Headers(request.headers);
headers.set('X-Forwarded-For', request.headers.get('CF-Connecting-IP') || '');
headers.delete('Cookie');
return fetch(upstream, { method: request.method, headers, body: request.body });
},
};
// Node 18 or later.
const express = require('express');
const UPSTREAM = 'https://t.tallybyoutpost.com';
const app = express();
app.set('trust proxy', true); // when Express runs behind a proxy, so req.ip is the visitor's
app.get('/js/script.js', async (req, res) => {
const upstream = await fetch(UPSTREAM + '/script.js');
res.set('Content-Type', 'application/javascript; charset=utf-8');
res.set('Cache-Control', upstream.headers.get('cache-control') || 'public, max-age=3600');
res.send(await upstream.text());
});
app.post('/api/event', express.text({ type: '*/*', limit: '8kb' }), (req, res) => {
fetch(UPSTREAM + '/api/event', {
method: 'POST',
headers: {
'Content-Type': 'text/plain',
'User-Agent': req.get('user-agent') || '',
'X-Forwarded-For': req.ip,
},
body: req.body,
}).catch(() => {});
res.status(202).end();
});
05Comprueba que funciona
¿Falta algo o no coincide con lo que ves? Escribe a support@tallybyoutpost.com y dinos qué página.