All docs

Ad blockers & proxy

Ad blockers mostly match on known analytics hostnames. Serve the script and its events from your own domain and there’s no such hostname to match.

On Cloudflare Workers

Your Worker sits between the visitor and DataPenny, so it needs to pass along who really called. Make a token under Setup → Ad blockers & proxy (each site has its own), then add this to the Worker that serves your site:

const DATAPENNY = 'https://YOUR-DATAPENNY-URL';
const DATAPENNY_TOKEN = 'dpx_YOUR_TOKEN'; // this site only; store it as a secret

async function datapennyProxy(request) {
  const url = new URL(request.url);
  if (url.pathname === '/js/script.js') {
    return fetch(DATAPENNY + '/js/script.js', { cf: { cacheTtl: 3600, cacheEverything: true } });
  }
  if (url.pathname === '/api/event' && request.method === 'POST') {
    const cf = request.cf || {};
    const headers = new Headers(request.headers);
    headers.delete('cookie'); // your cookies never leave your domain
    headers.set('x-dp-proxy', DATAPENNY_TOKEN);
    headers.set('x-dp-ip', request.headers.get('CF-Connecting-IP') || '');
    headers.set('x-dp-ua', request.headers.get('User-Agent') || '');
    headers.set('x-dp-geo', JSON.stringify({ country: cf.country, region: cf.region, city: cf.city,
      latitude: cf.latitude, longitude: cf.longitude, asn: cf.asn }));
    return fetch(DATAPENNY + '/api/event', { method: 'POST', headers, body: request.body });
  }
  return null; // not ours: carry on
}

Call datapennyProxy(request) first in your fetch handler, then load the script from your own domain:

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

On Next.js and Vercel

Add rewrites to next.config.js, then load the script from your own domain as above. Vercel’s location headers are read for you, so no token is needed.

module.exports = {
  async rewrites() {
    return [
      { source: '/js/script.js', destination: 'https://YOUR-DATAPENNY-URL/js/script.js' },
      { source: '/api/event', destination: 'https://YOUR-DATAPENNY-URL/api/event' },
    ];
  },
};

Anywhere else

Any reverse proxy works. Forward /js/script.js and /api/event to your DataPenny address, and send the same x-dp-* headers.