Next.js rewrites reverse proxy
Contents
- If you use a self-hosted proxy, PostHog can't help troubleshoot. Use our managed reverse proxy if you want support.
- Use domains matching your PostHog region:
us.i.posthog.comfor US,eu.i.posthog.comfor EU. - Don't use obvious path names like
/analytics,/tracking,/telemetry, or/posthog. Blockers will catch them. Use something unique to your app instead.
This guide shows you how to use Next.js rewrites as a reverse proxy for PostHog.
How it works
Next.js rewrites map incoming request paths to different destinations. When you add PostHog rewrites, Next.js fetches content from PostHog's servers and returns it under your domain.
Here's the request flow:
- User triggers an event in your app
- Request goes to your domain (e.g.,
yourdomain.com/ph) - Next.js matches the request against your rewrite rules
- Next.js fetches the response from PostHog's servers
- Next.js returns PostHog's response under your domain
This works because the rewrite happens server-side, so the browser only sees requests to your domain. Ad blockers that filter by domain won't block these requests.
Rewrites work best when self-hosting Next.js or using Vercel. Some hosting platforms modify headers during rewrites, causing 503 or 400 errors.
If you encounter issues, try Next.js proxy (formerly middleware) or a platform-specific proxy like Netlify.
Prerequisites
This guide works with any Next.js project using the app router or pages router.
Setup
- 1
Add rewrites to next.config.js
Add a
rewrites()function and theskipTrailingSlashRedirectoption to yournext.config.js:JavaScriptReplace
uswitheufor EU region.Here's what each part does:
- The first rewrite routes static asset requests to PostHog's asset server. This serves the JavaScript SDK and other static files.
- The second rewrite routes all other requests to PostHog's main API. This handles event capture, feature flags, and session recordings.
skipTrailingSlashRedirectprevents Next.js from redirecting URLs with trailing slashes. PostHog's API uses trailing slashes (like/e/), and without this setting, Next.js would redirect them and break event capture.
The static rewrite must come first. Next.js evaluates rewrites in order, so if the catch-all rule came first, it would match
/ph/static/*before the static-specific rule.See Next.js rewrites documentation for more details.
- 2
Update your PostHog SDK
In your application code, update your PostHog initialization to use your proxy path:
The
api_hosttells the SDK where to send events. Using a relative path ensures requests go to your domain. Theui_hostmust point to PostHog's actual domain so features like the toolbar link correctly. - 3
Deploy your changes
Commit and push your changes. Restart your dev server if testing locally, as Next.js doesn't hot-reload config changes.
Verify your setup
CheckpointConfirm events are flowing through your proxy:
- Open your browser's developer tools and go to the Network tab
- Navigate to your site or trigger an event
- Look for requests to your domain with your proxy path (e.g.,
yourdomain.com/ph) - Verify the response status is
200 OK - Check the PostHog app to confirm events appear in your activity feed
If you see errors, check troubleshooting below.
Troubleshooting
503 or 400 errors
Some hosting platforms modify headers during rewrites, breaking the proxy. This commonly happens with Heroku and Netlify.
Solutions:
- Use Next.js proxy (formerly middleware) for more control over the request
- Use a platform-specific proxy like Netlify redirects
- Self-host Next.js or use Vercel
Rewrites not working
If requests to your proxy path return 404:
- Verify your
next.config.jsis in the project root - Restart your dev server after changing the config
- Check the rewrite order: static assets rule must come before the catch-all
Trailing slash conflicts with SEO
The skipTrailingSlashRedirect setting is required for PostHog API requests but can cause SEO issues if pages become accessible at both /page and /page/.
Solutions:
- Handle trailing slash redirects in Next.js middleware for non-PostHog routes
- Use
<link rel="canonical">to specify the preferred URL for search engines - Ensure your sitemap only includes one URL format
401 errors or "No project API key provided"
If you see authentication errors and have verified your API key is correct, this usually indicates a region mismatch. Ensure the domains in your rewrites match your PostHog project's region (us or eu).
Some hosting platforms also strip the request body during rewrites, losing the API key. If this happens, use Next.js proxy instead.