siteline Start free trial Log in

How to proxy the SiteLine script

See your data

The default snippet loads script.js from SiteLine and posts events to SiteLine. Plenty of browser filter lists treat that as a tracker and eat it. A first-party reverse proxy serves both paths from your host so more events survive. More is not all. Filter lists also match generic paths, inline patterns, and CNAME-uncloaked hosts. Do not sell "unblockable analytics" to a client after this change.

SiteLine does not manage custom CNAMEs in this version. You configure nginx, Caddy, Cloudflare, Vercel rewrites, or whatever already terminates TLS for the site. Docs with copy-paste configs: first-party proxy.

What you must proxy

Two paths, nothing else is required:

Then the snippet becomes same-origin:

<script
    defer
    data-site-id="YOUR_SITE_ID"
    data-endpoint="/api/analytics/event"
    src="/js/script.js"
></script>

Relative data-endpoint is correct after the proxy exists. Before the proxy exists, relative collect posts into your app and 404s. If you are mid-migration, keep an absolute SiteLine endpoint until both routes respond.

The browser script can also derive collect from src when data-endpoint is omitted. With src="/js/script.js" that derivation is same-origin /api/analytics/event, which is what you want only if that route is proxied.

There is a collect alias at POST /js/event. You do not need to proxy it unless you point data-endpoint there. Stick to /api/analytics/event.

1. Enable analytics and note the origin

Enable the domain in SiteLine, copy YOUR_SITE_ID, and note YOUR_SITELINE_ORIGIN (the host that currently serves /js/script.js). You will proxy_pass to that origin. Keep the hostname allowlist on the visitor-facing hosts (example.com, www.example.com), not on SiteLine's host. The payload hostname is what the browser sees.

2. Forward the two paths without rewriting them into junk

The failure mode is stripping or prefixing the upstream path. /js/script.js must still be /js/script.js on SiteLine. Collect must remain POST with the JSON body intact.

nginx (from the docs):

location = /js/script.js {
  proxy_pass https://YOUR_SITELINE_ORIGIN/js/script.js;
  proxy_set_header Host YOUR_SITELINE_ORIGIN;
  proxy_ssl_server_name on;
}

location = /api/analytics/event {
  proxy_pass https://YOUR_SITELINE_ORIGIN/api/analytics/event;
  proxy_set_header Host YOUR_SITELINE_ORIGIN;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_ssl_server_name on;
}

Vercel rewrites in vercel.json map the same two sources to the same two destinations. Confirm POST bodies are forwarded.

Cloudflare: a Worker (or equivalent reverse-proxy rule) that only handles those two paths, sets Host to the upstream host, and returns the upstream response. Route it so /js/script.js and /api/analytics/event hit the Worker before your origin app.

Caddy: reverse_proxy both routes; watch handle_path versus handle so you do not drop /js/script.js off the upstream. The proxy docs include a Caddyfile skeleton.

Forward X-Forwarded-For and X-Forwarded-Proto on collect. Country and visitor hashing look at the request SiteLine actually receives. If every event looks like it came from your proxy's IP, you broke forwarding.

3. Swap the snippet

Replace the absolute SiteLine src and data-endpoint with the same-origin versions above. React SDK: set endpoint to /api/analytics/event (or the full https://your-domain/api/analytics/event). Do not leave endpoint pointing at SiteLine while script.js is first-party, or the opposite. Both must be first-party or you only half-fixed ad-blocker loss.

If the app is a SPA on a different subdomain than the marketing site, proxy on that subdomain too, or events from the app origin will miss the allowlist and/or the proxy.

4. Prove it from the browser

  1. Open DevTools → Network. Reload. script.js should be your host, status 200, JavaScript.
  2. You should see a POST to your host /api/analytics/event (or /js/event if you pointed there), JSON body, not a CORS failure.
  3. SiteLine Live should move.
  4. Optionally load the page with a popular blocker enabled. Some events will still vanish. That is expected.

If the POST is 404, the rewrite never hit. If it is 403/CORS, you are still calling SiteLine cross-origin without the proxy, or calling a different path. If Live is empty but POST is 200, check the public id and hostname allowlist.

5. Do not proxy the dashboard

This is not "put SiteLine behind my domain." You are only shielding the browser tracker. The dashboard, Search Console import, billing, and MCP stay on SiteLine. You still log into SiteLine.

What this does not do

FAQ

Can SiteLine issue a CNAME for analytics.example.com?

Not in this version. You reverse-proxy two paths on a host you already control. If you want a subdomain, you terminate TLS and proxy those paths yourself.

Should data-endpoint stay absolute after proxying?

Absolute https://your-domain/api/analytics/event is fine. Relative /api/analytics/event is also fine on that domain. Absolute https://YOUR_SITELINE_ORIGIN/... undoes the proxy for collect. Mix-and-match is how people think the proxy "doesn't work."

Will this hide SiteLine from my privacy policy?

No. You still send page URLs, referrers, event names, and optional properties to SiteLine. Cookieless is not invisible. The hashing details belong in the product privacy model, not in a proxy config.