Rankealo

Cloudflare Worker

A small Worker in front of your site sees every request, including ones served from Cloudflare's cache. It reports AI crawler visits to Rankealo and passes everything else straight to your site.

Prerequisites#

  • Your domain on Cloudflare with the proxy on (orange cloud) for the hostname you want to track. Any Cloudflare plan works, including Free.
  • Your site token and website id from Bot traffic → Agent Analytics Setup in the app. The snippet there already has both filled in; the examples on this page use YOUR_SITE_TOKEN and YOUR_WEBSITE_ID. See the HTTP API reference for the full payload.

Best option for hosted builders

Webflow, Framer, Squarespace, Shopify, and WordPress.com do not let you run server code. If the domain is proxied through Cloudflare, this Worker is how you track crawlers on them.

Steps#

  1. 1

    Create a Worker

    In the Cloudflare dashboard, open Workers & Pages → Createand start from the "Hello World" template.
  2. 2

    Paste the code

    Click Edit code, replace everything with the snippet (from Agent Analytics Setup, or below with your values), and Deploy.
  3. 3

    Add a route

    In the Worker's Settings → Domains & Routes, add a route such as www.your-site.com/* on your zone. Add one for the bare domain too if it serves pages.
js
export default {
  async fetch(request, env, ctx) {
    const ua = request.headers.get("user-agent") || "";
    if (/gptbot|chatgpt-user|oai-searchbot|oai-adsbot|claudebot|claude-searchbot|claude-user|anthropic-ai|perplexitybot|perplexity-user|google-extended|googlebot|googleother|bingbot|duckassistbot|applebot|meta-externalagent|amazonbot|bytespider|ccbot|mistralai-user/i.test(ua)
        && (request.method === "GET" || request.method === "HEAD")) {
      const url = new URL(request.url);
      ctx.waitUntil(fetch("https://app.rankealo.ai/api/ai-visibility/crawler-hits/ingest", {
        method: "POST",
        headers: { "content-type": "application/json", authorization: "Bearer YOUR_SITE_TOKEN" },
        body: JSON.stringify({
          websiteId: "YOUR_WEBSITE_ID",
          domain: url.hostname,
          href: url.protocol + "//" + url.host + url.pathname,
          ai: {
            userAgent: ua,
            ip: request.headers.get("CF-Connecting-IP"),
            source: "server_middleware",
          },
        }),
      }).catch(() => {}));
      const snap = await fetch("https://app.rankealo.ai/api/ai-visibility/bot-snapshot?websiteId=YOUR_WEBSITE_ID&path=" + encodeURIComponent(url.pathname), {
        headers: { authorization: "Bearer YOUR_SITE_TOKEN" },
      }).catch(() => null);
      if (snap && snap.ok) {
        const html = await snap.text();
        if (html && html.length > 200) {
          return new Response(html, { status: 200, headers: { "content-type": "text/html; charset=utf-8" } });
        }
      }
    }
    return fetch(request);
  },
};

What is sent#

  • URLScheme, host, and path. The query string is never sent.
  • User agentUsed to identify the crawler.
  • IPFrom CF-Connecting-IP; hashed on arrival, never stored raw.
  • Website idTies the hit to your site and token.

The report is sent with ctx.waitUntil, so the response is never held back. When bot rendering is on for your site, AI crawlers get a stored HTML copy of the page; otherwise the request goes to your site unchanged.

Limitations#

  • The snippet reports AI crawlers only (OpenAI, Anthropic, Perplexity, Google-Extended). Googlebot and Bingbot are not sent. Use Logpush or the HTTP API if you need search crawlers too.
  • Workers on the Free plan have a daily request limit. The Worker runs on every request on its route, not only crawler ones, so check your plan on high-traffic sites.
  • No status code is sent, because the Worker reports before your site responds.

Confirm data is flowing#

  1. 1
    In Rankealo, open Bot traffic → Agent Analytics Setup.
  2. 2
    Press Check now in step 3. Once a crawler has visited, it shows Receiving data with the time of the last hit.
  3. 3
    Open the Bot traffic tab to see hits by crawler and by page.

The first hit depends on when a crawler next visits, which can take up to 24 hours. To test right away, request a page with a crawler user agent, for example curl -A "GPTBot/1.2" https://www.your-site.com/, then press Check now. A test like this is recorded as a claimed identity, like any hit without CDN verification.

Troubleshooting#

The Worker never runs+
Check the route pattern matches the hostname you request (www vs bare domain) and that the DNS record is proxied (orange cloud), not DNS-only.
Check now says No data received+
Request a page with curl -A "GPTBot/1.2" and check again. If it is still empty, open the Worker logs (Observability) and look for errors from the fetch to Rankealo.
My site broke after adding the Worker+
The snippet only intercepts crawler requests and returns fetch(request) for everything else. If you merged it into an existing Worker, make sure the final return still calls your original logic.

Still stuck? Contact support

Reading is step one. Measuring your AI visibility is step two.

Rankealo tracks how often your brand is mentioned and cited across the major AI engines, then helps you publish the pages that close the gaps.