Skip to Content

Apache

Use mod_proxy and mod_headers to add proxy rules to your virtual host. Snow’s Settings → Proxy tab generates the ready-to-paste config for your site.

Required modules

Enable these Apache modules before adding the config:

a2enmod proxy proxy_http headers ssl systemctl reload apache2

On RPM-based systems (RHEL, Rocky, AlmaLinux), these modules are typically already loaded via LoadModule in the main config. Confirm with httpd -M | grep -E 'proxy|headers'.


Proxy only the script. Events go directly from the visitor’s browser to the Snow API.

<VirtualHost *:443> ServerName yourdomain.com # ... your existing virtual host config ... SSLProxyEngine on SSLProxyCheckPeerName on ProxyPass /sa/sa.js https://api.snowanalytics.app/sa.js ProxyPassReverse /sa/sa.js https://api.snowanalytics.app/sa.js <Location /sa/sa.js> RequestHeader set Host "api.snowanalytics.app" </Location> </VirtualHost>

Then update your embed to set data-api-url:

<script defer src="https://yourdomain.com/sa/sa.js" data-site="YOUR_SITE_ID" data-api-url="https://api.snowanalytics.app/api/collect" data-domain="yourdomain.com"></script>

The data-api-url attribute tells sa.js to post events directly to the Snow API. Apache is not in the path for events, so the real visitor IP reaches Snow untouched.


Full mode (script and events)

Proxy both paths. You must forward the real visitor IP. Otherwise every visitor geolocates to your server’s city.

Enable Secure proxy in Settings → Proxy before adding the X-Snow-Proxy-Secret header. The secret is shown once when you enable it.

<VirtualHost *:443> ServerName yourdomain.com # ... your existing virtual host config ... SSLProxyEngine on SSLProxyCheckPeerName on # Script proxy ProxyPass /sa/sa.js https://api.snowanalytics.app/sa.js ProxyPassReverse /sa/sa.js https://api.snowanalytics.app/sa.js <Location /sa/sa.js> RequestHeader set Host "api.snowanalytics.app" </Location> # Event proxy ProxyPass /sa/api/collect https://api.snowanalytics.app/api/collect ProxyPassReverse /sa/api/collect https://api.snowanalytics.app/api/collect <Location /sa/api/collect> RequestHeader set Host "api.snowanalytics.app" # Forward the real visitor IP RequestHeader set X-Snow-Client-IP "%{REMOTE_ADDR}s" RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s" # Secure proxy secret (from Settings → Proxy) RequestHeader set X-Snow-Proxy-Secret "YOUR_PROXY_SECRET" # Do not forward visitor cookies or auth RequestHeader unset Cookie RequestHeader unset Authorization </Location> </VirtualHost>

Then update your embed to point events through your domain:

<script defer src="https://yourdomain.com/sa/sa.js" data-site="YOUR_SITE_ID" data-api-url="/sa/api/collect" data-domain="yourdomain.com"></script>

%{REMOTE_ADDR}s is the IP of the connection Apache actually receives. If Apache sits behind a load balancer, this may be the upstream proxy’s IP. In that case, use %{X-Forwarded-For}i (the inbound header) instead, but only if your upstream load balancer sets it from the real socket. See Forwarding the visitor IP for the full details.

Key directives explained

DirectiveWhy it’s here
SSLProxyEngine onEnables TLS for outbound proxy connections to the Snow API.
ProxyPass / ProxyPassReverseRoutes the path to the upstream Snow URL and rewrites redirects back.
RequestHeader set HostSends the correct Host header upstream. Required for SNI.
X-Snow-Client-IPThe real visitor IP, trusted by Snow when the secret matches.
X-Snow-Proxy-SecretAuthenticates your proxy so Snow trusts X-Snow-Client-IP.
RequestHeader unset CookieStrips visitor cookies. Do not forward them upstream.

Verify

Generate some traffic, then check Analytics → Locations. A correct setup shows a realistic country distribution, not everything from one city. See Verify it’s working.