Cloudflare
A Worker on your own zone serves the script from your domain, passes its counts on, and says exactly where each visitor is.
If your site is on Cloudflare, a Worker on your own zone can pass both paths on, and knows exactly where
each visitor is. Create a Worker with this code, and add two routes for it under its settings, such as
example.com/js/tally.js and example.com/api/tally:
export default {
async fetch(request) {
const { pathname } = new URL(request.url);
if (pathname === '/js/tally.js') return fetch('https://fiveb.ar/js/tally.js');
const cf = request.cf || {};
const headers = new Headers({
'Content-Type': 'text/plain',
'User-Agent': request.headers.get('User-Agent') || '',
'X-Fivebar-IP': request.headers.get('CF-Connecting-IP') || '',
});
const origin = request.headers.get('Origin');
if (origin) headers.set('Origin', origin);
const place = {
'X-Fivebar-Country': cf.country,
'X-Fivebar-City': cf.city,
'X-Fivebar-ASN': cf.asn,
};
for (const [name, value] of Object.entries(place)) {
if (value) headers.set(name, encodeURIComponent(value));
}
return fetch('https://fiveb.ar/api/tally', { method: 'POST', headers, body: request.body });
},
};It passes on only what fivebar reads. A Worker has to name the visitor in X-Fivebar-IP:
Cloudflare replaces X-Forwarded-For on a request from one of its sites to another. See Cloudflare’s
help on routes.
Load the script
Once the proxy is live, load the script from your own domain. It sends its counts to the host it was loaded from, so nothing else changes:
<script async data-domain="example.com" src="/js/tally.js"></script>Then check it works. If either path is already taken on your site, see Other paths. Proxying says how it works and which headers name the visitor.