Proxy the script through your domain

Serve the tracking script from your own domain with nginx, PHP, or Caddy, so ad blockers do not stop it.

Some ad blockers block requests to analytics domains, and visitors who use them are not counted. With a proxy, the script and its data go through your own domain, for example https://example.com/a/script.js. Your server passes them on to Dodolytics.

A proxy is optional, and it needs a change to your server. If you are not sure, use the normal tracking script.

How it works

  • Your server serves the script at an address on your domain, and it sends the script's data on to Dodolytics.
  • You change the script tag: src is your address of the script, and data-api is your address for the data.
  • Your server tells Dodolytics the visitor's IP address in the X-Dodolytics-Visitor-IP header. Dodolytics uses it only to count unique visitors and for your excluded IP addresses, the same as without a proxy. It is not stored.

The country of your visitors

Without a proxy, Dodolytics gets the country, region, and city of each visitor from Cloudflare. Through a proxy, the request comes from your server, so your server must send these values. It can, if your own site is behind Cloudflare: the snippets below pass on Cloudflare's CF-IPCountry, CF-Region, and CF-IPCity headers. For region and city, turn on Add visitor location headers in your Cloudflare dashboard.

If your site is not behind Cloudflare, visits through the proxy have no location. The Countries report shows them as unknown. Dodolytics never uses your server's own location for them.

Way 1: nginx

Add these two blocks inside the server { } block of your website:

location = /a/script.js {
    proxy_pass https://dodolytics.com/tracker.js;
    proxy_pass_request_headers off;
    proxy_set_header Host dodolytics.com;
    proxy_ssl_server_name on;
}

location = /a/event {
    proxy_pass https://dodolytics.com/collect;
    proxy_pass_request_headers off;
    proxy_set_header Host dodolytics.com;
    proxy_set_header Content-Type $content_type;
    proxy_set_header User-Agent $http_user_agent;
    proxy_set_header X-Dodolytics-Visitor-IP $remote_addr;
    proxy_set_header X-Dodolytics-Country $http_cf_ipcountry;
    proxy_set_header X-Dodolytics-Region $http_cf_region;
    proxy_set_header X-Dodolytics-City $http_cf_ipcity;
    proxy_ssl_server_name on;
}
  • proxy_pass_request_headers off keeps your visitors' cookies on your server. Only the headers in the block are sent.
  • If your site is behind Cloudflare and nginx does not use the real_ip module, $remote_addr is a Cloudflare address. Use $http_cf_connecting_ip instead.

Run sudo nginx -t, then sudo systemctl reload nginx.

Way 2: PHP

Save this file on your website as a.php, next to your index.php. It needs PHP with the curl extension. It keeps a copy of the script for one hour.

<?php
// Dodolytics proxy: GET returns the script, POST sends the data on.
$base = 'https://dodolytics.com';

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $cache = sys_get_temp_dir() . '/dodolytics-script.js';
    if (!is_file($cache) || filemtime($cache) < time() - 3600) {
        $script = @file_get_contents($base . '/tracker.js');
        if ($script !== false && $script !== '') {
            file_put_contents($cache, $script, LOCK_EX);
        }
    }
    if (!is_file($cache)) {
        http_response_code(502);
        exit;
    }
    header('Content-Type: application/javascript; charset=UTF-8');
    header('Cache-Control: public, max-age=3600');
    readfile($cache);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $headers = [
        'Content-Type: text/plain',
        'X-Dodolytics-Visitor-IP: ' . ($_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? ''),
    ];
    foreach (['HTTP_CF_IPCOUNTRY' => 'Country', 'HTTP_CF_REGION' => 'Region', 'HTTP_CF_IPCITY' => 'City'] as $key => $name) {
        if (!empty($_SERVER[$key])) {
            $headers[] = 'X-Dodolytics-' . $name . ': ' . $_SERVER[$key];
        }
    }
    $ch = curl_init($base . '/collect');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => file_get_contents('php://input'),
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_USERAGENT => $_SERVER['HTTP_USER_AGENT'] ?? '',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 3,
    ]);
    curl_exec($ch);
    http_response_code(204);
    exit;
}

http_response_code(405);

With PHP, the script tag uses the same address for both: src="/a.php" and data-api="/a.php".

Way 3: Caddy

Add these two blocks inside the site block of your Caddyfile. This needs Caddy 2.7 or newer.

handle /a/script.js {
    rewrite * /tracker.js
    reverse_proxy https://dodolytics.com {
        header_up Host {upstream_hostport}
        header_up -Cookie
    }
}

handle /a/event {
    rewrite * /collect
    reverse_proxy https://dodolytics.com {
        header_up Host {upstream_hostport}
        header_up -Cookie
        header_up X-Dodolytics-Visitor-IP {client_ip}
        header_up X-Dodolytics-Country {header.CF-IPCountry}
        header_up X-Dodolytics-Region {header.CF-Region}
        header_up X-Dodolytics-City {header.CF-IPCity}
    }
}

Then run caddy reload. If your site is behind Cloudflare, set Caddy's trusted_proxies to Cloudflare's addresses, so that {client_ip} is the visitor and not Cloudflare.

Change the script tag

Replace the script on your pages. Keep your own website ID and any options. For nginx and Caddy:

<script defer src="/a/script.js" data-api="/a/event" data-website-id="site_xxxxxxxxxxxxxxxx"></script>

For the PHP file:

<script defer src="/a.php" data-api="/a.php" data-website-id="site_xxxxxxxxxxxxxxxx"></script>

You can use other addresses than /a/. Use names that do not say "analytics" or "tracker", because some ad blockers look for these words.

Check it

  1. Open your website with the developer tools open, on the Network tab.
  2. The script loads from your own domain, and a request to your data address has the status 204.
  3. Open Real-time in Dodolytics. Your visit shows there, with your country if your site is behind Cloudflare.

With a proxy, your Content Security Policy needs no change for Dodolytics: 'self' allows your own domain.

Related articles

Still need help? Ask on our feedback board or see all topics.