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:
srcis your address of the script, anddata-apiis your address for the data. - Your server tells Dodolytics the visitor's IP address in the
X-Dodolytics-Visitor-IPheader. 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 offkeeps 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_ipmodule,$remote_addris a Cloudflare address. Use$http_cf_connecting_ipinstead.
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
- Open your website with the developer tools open, on the Network tab.
- The script loads from your own domain, and a request to your data address has the status 204.
- 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
- Install the tracking script Add one script tag to plain HTML, WordPress, Webflow, Next.js, Google Tag Manager, Framer, Ghost, or Shopify.
- Tracking script options Turn link clicks, downloads, scroll depth, and hash routes on or off.
- Content Security Policy Allow the tracking script when your site sends a Content-Security-Policy header.
Still need help? Ask on our feedback board or see all topics.