VoidhashDocs
DocumentationAPI reference
Dashboard
Get started
Introduction
Quickstart
Setup
Setup overview
Create a project
Products and perks
Paywall locations
CLI
Paywall components
Components
Develop a component
Editor panels
Component definition
Publishing
Installing and capabilities
SDKs
Swift
Kotlin
React Native
Web
Store setup
Connect the App Store
Connect Google Play
Connect Stripe
API libraries
Node.js
PHP
Rust
Go
Resources
MCP server
Meta ads
Migrate in observer mode
Delete a person's data
Web SDK
Web quickstart
Identify users
Track events
Page views and attribution
Stripe revenue
Web-to-app handoff
First-party proxy
Feature flags
Troubleshooting

First-party proxy

Send the SDK's requests through your own domain, so ad blockers and tracking prevention do not drop them.

Ad blockers and browser tracking prevention block requests to analytics hosts they recognize. A visitor who blocks them is invisible to your funnels, and their purchase is credited to no campaign. Route the SDK's requests through a path on your own domain instead, such as https://www.example.com/vh, and they reach Voidhash like any other request your site makes.

The proxy forwards requests unchanged to https://api.voidhash.com. Everything the SDK sends, both API calls under /api/v1/ and events under /i/v1/, goes through it.

Pick a path

Choose a neutral path that is not used by your site, for example /vh. Avoid names such as /analytics, /track, or /voidhash; blocklists match on them.

Forward the path to Voidhash

Configure your host or server to forward every request under the path to https://api.voidhash.com, without the path prefix. Pick the recipe for your setup.

next.config.mjs
export default {
  async rewrites() {
    return [{ source: "/vh/:path*", destination: "https://api.voidhash.com/:path*" }];
  },
};

For a site on Vercel that does not use Next.js:

vercel.json
{
  "rewrites": [{ "source": "/vh/:path*", "destination": "https://api.voidhash.com/:path*" }]
}

A Worker on a route such as www.example.com/vh/*:

worker.ts
export default {
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);
    url.hostname = "api.voidhash.com";
    url.pathname = url.pathname.replace(/^\/vh/, "");
    return fetch(new Request(url, request));
  },
};
nginx.conf
location /vh/ {
  proxy_pass https://api.voidhash.com/;
  proxy_set_header Host api.voidhash.com;
  proxy_ssl_server_name on;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Whatever you use, keep the method, query string, body, and headers as they are, and do not cache the responses.

Point the SDK at the proxy

Set baseUrl to the proxy's URL, including the path:

const voidhash = createVoidhashClient({
  baseUrl: "https://www.example.com/vh",
  publishableKey: "vh_pk_…",
});

A relative path does not work; use the full URL, for example built from window.location.origin.

Check it

Open your site with the browser's developer tools on the Network tab. Requests go to /vh/i/v1/batch and /vh/api/v1/sdk/… on your own domain and answer with 2xx. Turn on an ad blocker and reload: the requests still go through.

Moving an existing site to the proxy keeps returning visitors as they are: their anonymous ID, consent choice, session, and queued events are stored per project, not per baseUrl.

Location behind a proxy

Voidhash derives a visitor's coarse location from the address of the request that reaches it. Behind a proxy, that address is the proxy's, so events sent through a proxy currently carry the proxy's location rather than the visitor's. Campaign attribution, sessions, identity, and revenue are unaffected.

Only some traffic through the proxy

To send only analytics through the proxy and keep API calls direct, set analytics.baseUrl instead:

const voidhash = createVoidhashClient({
  analytics: { baseUrl: "https://www.example.com/vh" },
  publishableKey: "vh_pk_…",
});

The proxy then only needs to forward /vh/i/v1/…. Ad blockers that block the API host still block feature flags and identify(), so forwarding everything is usually the better choice.

Self-hosted Voidhash

A self-hosted deployment already runs on a domain you control. Point baseUrl at it, or put it behind the same kind of proxy with your deployment's URL as the destination.

PreviousWeb-to-app handoffNextFeature flags

On this page

Pick a pathForward the path to VoidhashPoint the SDK at the proxyCheck itLocation behind a proxyOnly some traffic through the proxySelf-hosted Voidhash