Using Vercel rewrites as a reverse proxy

Last updated:

|Edit this page

On this page

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 of us in all domains (e.g. us.i.posthog.com -> eu.i.posthog.com)

Vercel supports rewrites which we can use as a reverse proxy. Create a vercel.json file and add a rewrites object from the /ingest route.

JSON
{
"rewrites": [
{
"source": "/ingest/static/:path*",
"destination": "https://us-assets.i.posthog.com/static/:path*"
},
{
"source": "/ingest/:path*",
"destination": "https://us.i.posthog.com/:path*"
}
]
}

Some frameworks, like SvelteKit and Astro, require a hungrier regex pattern like:

JSON
{
"rewrites": [
{
"source": "/ingest/static/:path(.*)",
"destination": "https://us-assets.i.posthog.com/static/:path*"
},
{
"source": "/ingest/: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 /ingest route of your domain as the API host in your PostHog initialization like this:

JavaScript
posthog.init('<ph_project_api_key>',
{
api_host: 'https://www.your-domain.com/ingest',
ui_host: '<ph_app_host>'
}
)

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.

Setup video

Questions?

  • Ab
    5 days ago

    Vercel / Cors

    I used the following .json to make it work:

    {
    "rewrites": [
    {
    "source": "/ingest/static/:path(.*)",
    "destination": "https://us-assets.i.posthog.com/static/:path"
    },
    {
    "source": "/ingest/:path(.*)",
    "destination": "https://us.i.posthog.com/:path"
    }
    ],
    "headers": [
    {
    "source": "/ingest/(.*)",
    "headers": [
    { "key": "Access-Control-Allow-Credentials", "value": "true" },
    { "key": "Access-Control-Allow-Origin", "value": "*" },
    { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
    { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
    ]
    }
    ]
    }
  • Bryan
    2 months ago

    Success for analytics, but failed for web vitals

    Following this doc successfully making PostHog is not blocked by an Adblock for web analytics such as PageView and PageLeave.

    image.png

    but it fails specifically for web-vitals even though the request has already been rewritten to my domain instead of post hog using vercel rewrites.

    image.png

    is this expected?

  • Ben
    5 months ago

    Getting 404 errors even while using the aggressive regex

    Any clues?

    Using:

    {
    "rewrites": [
    {
    "source": "/ingest/static/:path(.*)",
    "destination": "https://us-assets.i.posthog.com/static/:path*"
    },
    {
    "source": "/ingest/:path(.*)",
    "destination": "https://us.i.posthog.com/:path*"
    }
    ]
    }
    • Kevin
      5 months ago
      {
      "rewrites": [
      {
      "source": "/ingest/static/:path(.*)",
      "destination": "https://us-assets.i.posthog.com/static/:path"
      },
      {
      "source": "/ingest/:path(.*)",
      "destination": "https://us.i.posthog.com/:path"
      }
      ]
      }

      ^ Looks like from the comments below it's this.

  • Jim
    6 months ago

    Docs and video say different things

    In the video api_host is the live url but the docs on this page just say "/ingest". Which is correct?

    • David
      6 months ago

      Hey Jim,

      I believe the docs are more up to date.

      Given you're trying to setup a reverse proxy I can add you to the managed solution we plan on releasing to all shortly. Would you be interested in using that instead?

  • yobh
    10 months ago

    Error 405 Method Not Allowed

    Hi, im using a vitejs app hosted on vercel, and rewrites seems to be working, but the request generates 405 errors : image.png

    My setup: image.png

    image.png

    I havent setup any kind of CORS policies Did i miss something ? Thank you

    • Marcus
      9 months ago

      Hey Yobh, could you share a reproducible CodeSandBox example?

    • yobh
      Author9 months agoSolution

      Hey Marcus, sorry for the delay but I investigated more, and the solution was simple:
      The first rewrite

      "source": "/(.*)", "destination": "/"

      was disabling the two others.
      I moved it to the last position and the problem seems resolved!

  • Amitav
    a year ago

    CORS errors when rewriting

    CleanShot 2024-02-02 at 09.33.08@2x.png

    I'm seeing this come up, with next.js. Here's my vercel.json:

    {"rewrites": [
    {
    "source": "/ingest/:path*",
    "destination": "https://eu.posthog.com/:path*"
    }
    ]
    }

    Was seeing the same when I tried the Next.js setup too.

    • Kevin
      5 months ago

      Thanks so much, you just saved me a few hours of time.

Was this page useful?

Next article

Historical migrations overview

Historical migrations refer to ingesting and importing past data into PostHog for analysis. This includes: Migrating from a different tool or platform like Mixpanel , Amplitude , Heap , or LaunchDarkly . Migrating from a self-hosted PostHog instance to PostHog Cloud . Migrating from one PostHog Cloud instance to another , for example US -> EU. Adding past data from a third-party source into PostHog. What about exporting data from PostHog? Use our batch export feature to export data from…

Read next article

PostHog.com doesn't use third party cookies - only a single in-house cookie.

No data is sent to a third party.

Ursula von der Leyen, President of the European Commission