Nginx
Setup
Store the proxy key outside the main config, readable only by root:
set $x3_proxy_key "sk_3x_YOUR_PROXY_KEY";proxy_cache_path /var/cache/nginx/x3 levels=1:2 keys_zone=x3:1m max_size=20m inactive=1d use_temp_path=off;location ~ ^{{PROXY_PATH}}(/v1/(?:e|collect|cb|c/[^/]+|s/[A-Za-z0-9@._-]+))$ {
include /etc/nginx/x3-proxy-key.conf;
proxy_pass {{API_ORIGIN}}$1$is_args$args;
proxy_ssl_server_name on;
proxy_http_version 1.1;
proxy_set_header Host $proxy_host;
proxy_set_header Cookie "";
proxy_set_header Authorization "";
proxy_set_header X-Forwarded-For "";
proxy_set_header x-3x-client-ip $remote_addr;
proxy_set_header x-3x-client-country $http_cf_ipcountry;
proxy_set_header x-3x-proxy-key $x3_proxy_key;
proxy_hide_header Set-Cookie;
client_max_body_size 32k;
proxy_cache x3;
proxy_cache_methods GET HEAD;
proxy_cache_valid 200 1h;
proxy_cache_use_stale updating error timeout;
}sudo chmod 600 /etc/nginx/x3-proxy-key.conf
sudo nginx -t && sudo systemctl reload nginx$remote_addris the visitor's IP when Nginx faces the internet. Behind a load balancer or CDN, enable therealipmodule (set_real_ip_from+real_ip_header) so$remote_addris the real client, never a header a client can set.- Only
GETresponses are cached (scripts and client config); event POSTs always pass through. - Drop the
x-3x-client-countryline if no trustworthy geo header exists; the country stays empty.
Verify
curl -s -o /dev/null -w "%{http_code}\n" https://example.com{{PROXY_PATH}}/v1/s/x3.js
curl -s -o /dev/null -w "%{http_code}\n" https://example.com{{PROXY_PATH}}/v1/adminThe first prints 200, the second 404 (only the four path families are proxied). Then check that
POST {{PROXY_PATH}}/v1/e from a page returns 204.