Reverse proxy
Route SDK requests through your own domain to avoid ad blockers and keep data collection first-party.
Route SDK requests through your own domain to avoid ad blockers and keep data collection first-party. When a reverse proxy is configured, all requests appear to originate from your domain instead of a third-party analytics host.
#Why use a reverse proxy?
Ad blockers commonly block requests to known analytics domains and paths. A reverse proxy on your own domain makes SDK traffic indistinguishable from your regular API calls.
- Ad blocker avoidance — requests go through your domain, not a third-party analytics host.
- First-party cookies — cookies are set on your domain, improving identification accuracy.
- Privacy compliance — data stays within your infrastructure boundary.
#SDK endpoints
The SDK uses these short paths to minimise payload size and avoid ad-blocker pattern matching. Your reverse proxy must forward all of them — including the x-api-key request header — to your vTilt instance.
| Path | Purpose | Method |
|---|---|---|
/api/e | Event ingestion (pageviews, custom events, identify). | POST |
/api/d | Remote configuration. | GET |
/api/s | Session recording snapshots. | POST |
/gt/* | Google Tag gateway (gtag.js, collect, conversion) when destinations use proxied mode. | GET / POST |
/api/chat/* | Chat widget (settings, messages, channels). | GET / POST |
#SDK configuration
Set api_host to your proxy domain so all SDK traffic routes through it.
vt.init('YOUR_PROJECT_TOKEN', {
api_host: 'https://your-domain.com',
})#Next.js rewrites
Add these rewrites to your next.config.js to proxy vTilt requests through your Next.js app.
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{ source: '/api/e', destination: 'https://www.vtilt.com/api/e' },
{ source: '/api/d', destination: 'https://www.vtilt.com/api/d' },
{ source: '/api/s', destination: 'https://www.vtilt.com/api/s' },
{ source: '/gt/:path*', destination: 'https://www.vtilt.com/gt/:path*' },
{ source: '/api/chat/:path*', destination: 'https://www.vtilt.com/api/chat/:path*' },
]
},
}
module.exports = nextConfig#Nginx
Add location blocks to forward each path to your vTilt instance.
location /api/e {
proxy_pass https://www.vtilt.com/api/e;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/d {
proxy_pass https://www.vtilt.com/api/d;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/s {
proxy_pass https://www.vtilt.com/api/s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /gt/ {
proxy_pass https://www.vtilt.com/gt/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/chat/ {
proxy_pass https://www.vtilt.com/api/chat/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}#Cloudflare Workers
Deploy a Cloudflare Worker on your domain to proxy SDK requests.
const VTILT_HOST = 'https://www.vtilt.com'
export default {
async fetch(request) {
const url = new URL(request.url)
if (
url.pathname.startsWith('/api/e') ||
url.pathname.startsWith('/api/d') ||
url.pathname.startsWith('/api/s') ||
url.pathname.startsWith('/gt/') ||
url.pathname.startsWith('/api/chat/')
) {
const target = new URL(url.pathname + url.search, VTILT_HOST)
const proxyReq = new Request(target, {
method: request.method,
headers: request.headers,
body: request.body,
})
proxyReq.headers.set(
'X-Forwarded-For',
request.headers.get('CF-Connecting-IP') || '',
)
return fetch(proxyReq)
}
return fetch(request)
},
}#Script tag with proxy
When using the script tag snippet, set data-host to your proxy domain.
<script
data-token="YOUR_PROJECT_TOKEN"
data-host="https://your-domain.com"
src="https://your-domain.com/dist/array.js"
></script>