Skip to content

Preventing ad blockers from blocking Umami, using a Cloudflare worker [solution] #1025

@vitobotta

Description

@vitobotta

Hi, I thought I'd share this because I am sure others have the same problem - uBlock Origin and others blocking Umami.

The solution I am using involves Cloudflare workers, which have an incredible free tier. So all you need to do is create a Cloudflare worker with the following code:

const ScriptName = '/whatever.js';
const Endpoint = '/foo/bar';

const ScriptWithoutExtension = ScriptName.replace('.js', '')

addEventListener('fetch', event => {
    event.passThroughOnException();
    event.respondWith(handleRequest(event));
})

async function handleRequest(event) {
  const pathname = new URL(event.request.url).pathname
  const [baseUri, ...extensions] = pathname.split('.')


  const clientIP = event.request.headers.get("CF-Connecting-IP")
  if (clientIP === "x.x.x.x") {
   return new Response("Ignore IP x.x.x.x", { status: 403 }) // just to exclude my ip from tracking, can also be done with an environment variable in Umami config
  }

  if (baseUri.endsWith(ScriptWithoutExtension)) {
      return getScript(event, extensions)
  } else if (pathname.endsWith(Endpoint)) {
      return postData(event)
  }
  return new Response(null, { status: 404 })
}

async function getScript(event, extensions) {
    let response = await caches.default.match(event.request);
    if (!response) {
        response = await fetch("https://mydomain.com/umami.js");
        var js = await response.text()
        
        js = js.replace("/api/collect" , Endpoint)

        response = new Response(js, {
            headers: response.headers
        }) 

        event.waitUntil(caches.default.put(event.request, response.clone()));
    }

    return response;
}

async function postData(event) {
    const request = new Request(event.request);
    request.headers.delete('cookie');
    return await fetch("https://mydomain.com/api/collect", request);
}

Then you need to tweak the Umami snippet for your site:

<script async defer data-website-id="..." src="https:///<cloudflare worker hostname>/whatever.js"></script>

That's it. Just customize the names of the script and the endpoint for the POST requests with unique names and no ad blocker should be able to block Umami, because the script name, endpoint path, and even the content of the script are unique.

Hope this helps others :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions