server { | |
listen 80; | |
server_name your.domain.com; | |
location = /analytics.js { | |
# you have to compile nginx with http://nginx.org/en/docs/http/ngx_http_sub_module.html (this is not default) | |
# and http://nginx.org/en/docs/http/ngx_http_proxy_module.html (it's a default module) | |
proxy_set_header Accept-Encoding ""; | |
sub_filter 'www.google-analytics.com' 'your.domain.com'; | |
sub_filter_types *; | |
sub_filter_once off; | |
proxy_pass https://www.google-analytics.com/analytics.js; | |
break; | |
} | |
location / { | |
proxy_pass http://www.google-analytics.com/; | |
} | |
} |
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | |
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | |
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | |
})(window,document,'script','//your.domain.com/analytics.js','ga'); | |
# after this run your regular ga code | |
ga('create', 'UA-XXXXXXX-Y', 'auto'); | |
ga('set', 'userId', 'your logged user id'); | |
ga('send', 'pageview'); |
if you are using cloudflare use real ip module to get the ip and set it in proxy query string
http://nginx.org/en/docs/http/ngx_http_realip_module.html
add this lines inside "server" block:
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;
# use any of the following two
real_ip_header CF-Connecting-IP;
and then change the proxy_pass to:
proxy_pass http://www.google-analytics.com/$uri$is_args$args&uip=$remote_addr;
Hi @paivaric,
I checked my configuration several times; I'm pretty sure I didn't make any mistake in following your instructions.
However, I'm getting a lot of these errors:
upstream timed out (110: Connection timed out) while connecting to upstream,
Does it happen to you too?
Note that I'm not using the userId, nor Cloudflare.
Regards,
Benoit
Nevermind, I found the answer.
For some reason, IPv6 is not working correctly on my box.
Nginx timed out when it used the IPv6 address of www.google-analytics.com
.
The solution was to add the following line to the server
block:
resolver 8.8.8.8 ipv6=off;
And wait a long time (I would say 10m) until the cache expires.
I found a mistake in the NGINX configuration shown at the top.
It should not be:
proxy_pass http://www.google-analytics.com/;
but it should be:
proxy_pass http://www.google-analytics.com;
It's crucial to remove the trailing slash; otherwise, NGINX drops all the query parameters.
Some adblockers are strict and even block urls like '/r/collect/'
Sot he trick is to replace sub_filter 'r/collect' 'rrr/upstreamer';
then add a block of code
location /rrr/upstreamer/{
proxy_set_header Accept-Encoding "";
sub_filter 'www.google-analytics.com' 'subcode.example.com';
sub_filter_types *;
sub_filter_once off;
proxy_pass https://www.google-analytics.com/r/collect;
break;
}
This basically proxy all requests to google analytics, including the analytics.js download.
After download analytics.js the content of file is changed by nginx, replacing regular 'www.google-analytics.com' urls to your proxy domain.
So all your requests from your frontend will go to your proxy.
For it works, you just need to replace the redular '//www.google-analytics.com/analytics.js' in the frontend by '//your.domain.com/analytics.js'. Nothing else! Really!