Some visitors use adblockers that block third-party analytics scripts. When this happens, the Clickport tracker never loads and that visit is invisible to you. Depending on your audience, this can mean losing anywhere from 6% to 60% of your data.
Proxying the tracker through your own domain solves this. Instead of loading the script from clickport.io, visitors load it from your domain. Since it looks like a first-party request, adblockers let it through.
You need to proxy two things:
Your proxy forwards these requests to Clickport's servers. Visitors never see clickport.io in their browser's network tab, so adblocker filter lists do not match.
analytics, tracking, stats, plausible, or clickport in your proxy paths. Generic names like /js/app.js or /collect work well.
Once your proxy is set up, update the Clickport snippet on your site. The tracker automatically sends events to the same origin it was loaded from, so if the script loads from your domain, events go to your domain too.
<!-- Load tracker from your proxy -->
<script defer data-site="ck_your_key" data-domain="yoursite.com"
src="/js/app.js"></script>
If your script path and event path use different base URLs, you can override the event endpoint with cpConfig.api:
<script>
window.cpConfig = { api: '/collect' };
</script>
<script defer data-site="ck_your_key" data-domain="yoursite.com"
src="/js/app.js"></script>
This tells the tracker to send events to /collect/api/event instead of deriving the path from the script source.
Cloudflare Workers is a good option if your site already uses Cloudflare. The free tier handles 100,000 requests per day, which is more than enough for most sites.
In your Cloudflare dashboard, go to Workers & Pages and create a new Worker. Give it a generic name (the random default is fine).
Replace the default code with:
const SCRIPT_URL = 'https://clickport.io/tracker.js';
const SCRIPT_PATH = '/js/app.js';
const EVENT_PATH = '/api/event';
addEventListener('fetch', event => {
event.passThroughOnException();
event.respondWith(handleRequest(event));
});
async function handleRequest(event) {
const url = new URL(event.request.url);
if (url.pathname === SCRIPT_PATH) {
// Serve the tracker script (cached at the edge)
let response = await caches.default.match(event.request);
if (!response) {
response = await fetch(SCRIPT_URL);
event.waitUntil(caches.default.put(event.request, response.clone()));
}
return response;
}
if (url.pathname === EVENT_PATH) {
// Forward event beacons to Clickport
const request = new Request(event.request);
request.headers.delete('cookie');
return fetch('https://clickport.io/api/event', request);
}
return new Response(null, { status: 404 });
}
In your Worker's settings, go to Triggers → Routes and add a route for your domain:
*yoursite.com/js/* # matches the script path
*yoursite.com/api/* # matches the event path
<script defer data-site="ck_your_key" data-domain="yoursite.com"
src="/js/app.js"></script>
Since the script loads from your own domain, the tracker automatically sends events to yoursite.com/api/event. No cpConfig override needed.
If your site is deployed on Vercel, you can proxy the tracker using rewrite rules in vercel.json.
{
"rewrites": [
{
"source": "/js/app.js",
"destination": "https://clickport.io/tracker.js"
},
{
"source": "/collect/api/event",
"destination": "https://clickport.io/api/event"
}
]
}
<script>
window.cpConfig = { api: '/collect' };
</script>
<script defer data-site="ck_your_key" data-domain="yoursite.com"
src="/js/app.js"></script>
The cpConfig.api override is needed here because the script path (/js/) and event path (/collect/) use different prefixes.
On Netlify, you can proxy using a _redirects file in your publish directory.
Create or edit the _redirects file in your site's publish directory:
/js/app.js https://clickport.io/tracker.js 200
/collect/api/event https://clickport.io/api/event 200
The 200 status code is important. It tells Netlify to proxy the request (rewrite), not redirect. A 301 or 302 would send the browser to clickport.io directly, which defeats the purpose.
<script>
window.cpConfig = { api: '/collect' };
</script>
<script defer data-site="ck_your_key" data-domain="yoursite.com"
src="/js/app.js"></script>
src to a CDN URL, breaking the proxy. If this happens, disable "Bundle JS" and "Minify JS" in your site's build settings, or use an absolute URL (https://yoursite.com/js/app.js) instead of a relative path.
If you manage your own server with Nginx, add these location blocks to your server configuration.
proxy_cache_path /var/run/nginx-cache/cpcache levels=1:2
keys_zone=cpcache:10m inactive=30d max_size=100m;
server {
# ... your existing server config ...
location = /js/app.js {
proxy_pass https://clickport.io/tracker.js;
proxy_set_header Host clickport.io;
proxy_buffering on;
proxy_cache cpcache;
proxy_cache_valid 200 5m;
proxy_cache_use_stale updating error timeout http_500;
}
location = /collect/api/event {
proxy_pass https://clickport.io/api/event;
proxy_set_header Host clickport.io;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_http_version 1.1;
proxy_buffering on;
}
}
Update your snippet:
<script>
window.cpConfig = { api: '/collect' };
</script>
<script defer data-site="ck_your_key" data-domain="yoursite.com"
src="/js/app.js"></script>
/var/run/nginx-cache may not survive reboots. To make it persistent, create a systemd tmpfiles rule: echo "D /var/run/nginx-cache 0755 root root -" > /usr/lib/tmpfiles.d/nginx-cache.conf
After setting up the proxy, open your site in a browser and check the Network tab in developer tools:
/js/app.js). It should return status 200 with JavaScript content./collect/api/event). It should return status 200.If both requests succeed through your domain, the proxy is working. Enable an adblocker and repeat the test to confirm requests still go through.
Understanding this helps you debug proxy issues. The tracker determines where to send events in this order:
cpConfig.api is set, use that as the base URL and append /api/event.src attribute, strip /tracker.js (or whatever the filename is), and use that as the base URL.This means that if the script loads from https://yoursite.com/js/app.js, the tracker sends events to https://yoursite.com/js/api/event by default. If that path does not match your proxy config, set cpConfig.api to the correct base path.
X-Forwarded-For header. Clickport uses this header to determine the visitor's IP for geolocation. If your proxy does not forward it, all visitors will appear to come from your server's IP address.text/plain. This is intentional. Some proxies reject or transform application/json requests. Make sure your proxy forwards the body as-is without parsing or modifying it.