DocumentationLe servir depuis votre domaine

04 · Suivi

Servir le script depuis votre propre domaine

Deux chemins sur votre site, transmis à Tally, font du script et de ses événements des ressources first-party.

01Pourquoi le servir vous-même

Les bloqueurs de publicité bloquent les analytics d’après l’adresse depuis laquelle ils se chargent. Servis depuis votre propre domaine, le script et ses événements ne figurent pas sur leurs listes. Le cookie du visiteur n’en dépend pas : le script le dépose sur le domaine de votre page dans tous les cas.

02Deux chemins à transmettre

Sur votre siteTransmis vers
/js/script.jshttps://t.tallybyoutpost.com/script.js
/api/eventhttps://t.tallybyoutpost.com/api/event

Chargez ensuite le script depuis votre site. Il envoie les événements à /api/event sur sa propre adresse, si bien que rien d’autre ne change :

HTML
<script defer data-site="k3xq2mfa7twp" src="/js/script.js"></script>

Si votre site a déjà un /api/event, transmettez un autre chemin et indiquez-le au script avec data-api="/your/path".

03Ce que tout proxy doit faire

  • Transmettez le user agent : c’est ainsi que les robots sont filtrés.
  • Transmettez l’adresse IP du visiteur dans X-Forwarded-For : elle sert à trouver sa ville (et, sur un site sans cookie, à le compter), puis est écartée. Un serveur qui relaie ses visiteurs bénéficie du quota d’événements plus large d’un proxy, pour qu’ils ne partagent pas celui d’un seul navigateur.
  • Ne transmettez pas les cookies : ils ne sont pas lus.
  • Répondez immédiatement au navigateur si vous le souhaitez (202) : le script ignore toutes les réponses.

04Sur votre serveur

Afficher le code pour

// 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' },
    ];
  },
};

Sur Vercel, la réécriture transmet X-Forwarded-For. Une route /api/event propre à l’application est prioritaire : utilisez un autre chemin et 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, pour un site sur Vercel sans 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 définit lui-même X-Forwarded-For.

// 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();
});

05Vérifier que ça marche

Il manque quelque chose, ou ce n’est pas ce que vous voyez ? Écrivez à support@tallybyoutpost.com en précisant la page.