(Using Cloudflare Pages Functions as a Reverse Proxy)
Standard analytics trackers are blocked by approximately 20% of users due to ad blockers.
Clicky provides a solution—an anti-adblock proxy method—which works by:
To ad blockers, this appears as first-party traffic. And that's the trick. This is what allows it to bypass ad blockers. This guide shows you how to implement it using Cloudflare Pages Functions, with no nginx, Workers dashboard setup, or DNS changes.
Browser → static.getclicky.com (blocked)
We will proxy it like this:
Browser → yourdomain.com/<YOUR_CLICKY_JS_PATH>
→ Cloudflare Pages Function
→ static.getclicky.com
→ Response returned
Browser → yourdomain.com/<YOUR_CLICKY_BEACON_PATH>
→ Cloudflare Pages Function
→ in.getclicky.com
→ Response returned
Before beginning, confirm the following:
Your Pages project must already be connected to:
yourdomain.com
OR
yourdomain.pages.dev
Inside your Clicky dashboard (Prefs > Tracking code), you will see:
/XXXXXXXXXXXXX.js/YYYYYYYYYYYYYReplace in this guide:
<YOUR_CLICKY_JS_PATH> → your actual JS path<YOUR_CLICKY_BEACON_PATH> → your actual beacon path<YOUR_SITE_ID> → your numeric site ID (Ctrl+F & search "site_id" on the tracking code page to locate it)These values are unique to your Clicky account.
Inside your local project folder:
your-project/
│
├── functions/
│
└── (your other files)
Inside /functions, create two new files.
Create this file:
/functions/<YOUR_CLICKY_JS_PATH>.js
Example (if your path is /abc123def456g.js):
/functions/abc123def456g.js.js
Yes — .js.js is correct.
The first is part of Clicky’s required path;
the second is required because Cloudflare Functions must end in .js.
Paste this code:
export async function onRequest(context) {
const beaconPath = "/<YOUR_CLICKY_BEACON_PATH>";
const upstreamURL = `https://static.getclicky.com/js?in=${encodeURIComponent(beaconPath)}`;
const response = await fetch(upstreamURL, {
method: "GET",
headers: {
"User-Agent": context.request.headers.get("User-Agent") || "",
"Accept": "application/javascript"
}
});
const headers = new Headers();
headers.set("Content-Type", "application/javascript; charset=utf-8");
return new Response(response.body, {
status: response.status,
headers
});
}
Note that you need to insert your actual Clicky beacon path where indicated above.
Create this file:
/functions/<YOUR_CLICKY_BEACON_PATH>.js
Example:
/functions/789hij012klmn.js
Paste this code:
export async function onRequest(context) {
const request = context.request;
const url = new URL(request.url);
const upstreamURL = `https://in.getclicky.com/in.php${url.search}`;
const headers = {
"User-Agent": request.headers.get("User-Agent") || "",
"Referer": request.headers.get("Referer") || "",
"X-Forwarded-For": request.headers.get("CF-Connecting-IP") || "",
"X-Forwarded-Proto": "https",
"X-Forwarded-Host": url.hostname
};
const cookieHeader = request.headers.get("cookie") || "";
const ckyIgnore = cookieHeader.match(/_cky_ignore=[^;]+/)?.[0];
const ckyOsa = cookieHeader.match(/_cky_osa=[^;]+/)?.[0];
if (ckyIgnore || ckyOsa) {
headers["Cookie"] = [ckyIgnore, ckyOsa].filter(Boolean).join("; ");
}
const response = await fetch(upstreamURL, {
method: "GET",
headers
});
const safeHeaders = new Headers();
safeHeaders.set("Content-Type", "text/javascript; charset=utf-8");
return new Response(response.body, {
status: response.status,
headers: safeHeaders
});
}
According to Clicky docs, deploy first, test second, then install the custom tracking code last after successful testing.
Load the following two URLs which can be found on the same Clicky tracking code page:
https://yourdomain.com/<YOUR_CLICKY_JS_PATH>
https://yourdomain.com/<YOUR_CLICKY_BEACON_PATH>?site_id=<YOUR_SITE_ID>
Both should load JavaScript.
Now load the following URL (also found on the Clicky tracking code page):
https://yourdomain.com/<YOUR_CLICKY_BEACON_PATH>?site_id=<YOUR_SITE_ID>&ignore=YOUR_IGNORE_TOKEN&osa=1
According to Clicky docs, you should see the message: "setting proxy auto-ignore / osa cookie".
With Cloudflare Pages, this may appear differently.
The Clicky beacon endpoint is designed to be requested via image request or JavaScript in the background — not directly in a browser tab.
When loaded directly, Clicky may return _no_tracky_* JavaScript because it only counts valid beacon executions.
Seeing _no_tracky_* is normal. It does not mean the proxy is broken.
If all is well, install your new custom tracking code in your site's HTML, replacing the old standard code on all pages (it will look like this, but with your actual path and site ID):
<script async data-id="<YOUR_SITE_ID>" src="/<YOUR_CLICKY_JS_PATH>"></script>
Important:
src must be root-relative.static.getclicky.com.Note that your new tracking code should be located on the same Clicky tracking code page where you found the paths.
/<YOUR_CLICKY_JS_PATH> and /<YOUR_CLICKY_BEACON_PATH>Should you want to revert everything, simply:
/functions files