Clicky Analytics Anti-Adblock Tracking on Cloudflare Pages

(Using Cloudflare Pages Functions as a Reverse Proxy)


Overview

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.


How This Works (Architecture)

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

Phase 1 — Prerequisites

Before beginning, confirm the following:

1. Cloudflare Pages Project

2. Custom Domain Connected

Your Pages project must already be connected to:

yourdomain.com
OR
yourdomain.pages.dev

3. Clicky Anti-Adblock Paths

Inside your Clicky dashboard (Prefs > Tracking code), you will see:

Replace in this guide:

These values are unique to your Clicky account.


Phase 2 — Project Structure

Inside your local project folder:

your-project/
│
├── functions/
│
└── (your other files)

Inside /functions, create two new files.


Phase 3 — Create the JavaScript Proxy

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.


Phase 4 — Create the Beacon Proxy

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

Phase 5 — Deploy

According to Clicky docs, deploy first, test second, then install the custom tracking code last after successful testing.


Phase 6 — Test

Verify JavaScript Endpoint

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.


Phase 7 — Install Tracking Code

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:

Note that your new tracking code should be located on the same Clicky tracking code page where you found the paths.


Phase 8 — Deploy Again


Final Phase — Confirm It Works


Clean Removal

Should you want to revert everything, simply: