Note: 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.
Note: 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
)
If you are using Next.js, you can take advantage of rewrites to behave like a reverse proxy. To do so, add a rewrites()
function and the skipTrailingSlashRedirect
option to your next.config.js
file:
// next.config.jsconst nextConfig = {async rewrites() {return [{source: "/ingest/static/:path*",destination: "https://us-assets.i.posthog.com/static/:path*",},{source: "/ingest/:path*",destination: "https://us.i.posthog.com/:path*",},{source: "/ingest/decide",destination: "https://us.i.posthog.com/decide",},];},// This is required to support PostHog trailing slash API requestsskipTrailingSlashRedirect: true,}module.exports = nextConfig
Then configure the PostHog client to send requests via your rewrite.
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {api_host: "/ingest",ui_host: '<ph_app_host>'})
If this isn't working for you (returning
503
or400
errors), it may be an issue with how your hosting service (such as Heroku or Netlify) handles rewrites. You can write Next.js middleware or use a host-specific proxy (like Netlify) instead. For example, Netlify modifies theContent-Encoding
header when usingrewrites()
, which causes PostHog to fail to parse the request. This doesn't happen if you use their_redirects
file ornetlify.toml
options.