The following self-hosted proxy isn't provided by PostHog, so we can't take responsibility for it! If unsure, we recommend using our managed reverse proxy.
If you are using the EU cloud then use
eu
instead ofus
in all domains (e.g.us.i.posthog.com
->eu.i.posthog.com
).Avoid using generic or common path names like
/analytics
,/tracking
,/ingest
, or/posthog
for your reverse proxy. They will most likely be blocked. Instead, use a non-obvious path name or something random and unique to your application that's unlikely to appear in a filter list.
Vercel supports rewrites which we can use as a reverse proxy. Create a vercel.json
file and add a rewrites
object from a custom route.
{"rewrites": [{"source": "/<ph_proxy_path>/static/:path*","destination": "https://us-assets.i.posthog.com/static/:path*"},{"source": "/<ph_proxy_path>/:path*","destination": "https://us.i.posthog.com/:path*"}]}
Some frameworks, like SvelteKit and Astro, require a hungrier regex pattern like:
{"rewrites": [{"source": "/<ph_proxy_path>/static/:path(.*)","destination": "https://us-assets.i.posthog.com/static/:path*"},{"source": "/<ph_proxy_path>/:path(.*)","destination": "https://us.i.posthog.com/:path*"}]}
Note: Some frameworks, like T3 app, don't support Vercel rewrites well. If neither of these options work, we recommend trying another proxy method.
Once done, set the /<ph_proxy_path>
route of your domain as the API host in your PostHog initialization like this:
posthog.init('<ph_project_api_key>', {api_host: 'https://www.your-domain.com/ingest',ui_host: '<ph_app_host>',defaults: '2025-05-24',})
Once updated, deploy your changes on Vercel and check that PostHog requests are going to https://www.your-domain.com/ingest
by checking the network tab on your domain.