Vercel not sending the client’s IP address to Laravel backend on first SSR load (Nuxt 3)

I’m experiencing an issue with my setup where the client’s IP address isn’t forwarded correctly during the first SSR load of a page.

Backend: Laravel hosted on a VPS
Frontend: Nuxt 3 hosted on Vercel
Problem:
When a page is loaded for the first time with Server-Side Rendering (SSR), Vercel sends its own IP address instead of the client’s IP. This causes issues with my Laravel API, including:

429 errors due to rate limiting based on Vercel’s IP.
Incorrect geolocation since I use the client’s IP for location-based pricing and user experience.
However, this issue only happens on the first SSR load. For example, when a form request is made later, the correct client IP is sent.

What I’ve Tried:
I use the following plugin to make an initial request and load global values:ç

export default defineNuxtPlugin(async () => {
  const { products } = useProducts();
  const { limits } = useLimits();
  const route = useRoute();
  const sanctumClient = useSanctumClient();

  const { data, error } = await useAsyncData("globals", () =>
    sanctumClient("/globals"),
  );

  if (error.value) {
    if (error.value.statusCode === 503 && route.path !== "/maintenance") {
      await navigateTo("/maintenance");
    }

    if (route.path !== "/maintenance") {
      throw createError(error.value);
    }
  }

  if (data.value) {
    products.value = data.value.products;
    limits.value = data.value.limits;

    if (route.path === "/maintenance") {
      await navigateTo("/");
    }
  }
});

This issue also occurs in any other page that makes SSR calls, but only on the first load.

I enabled trustproxies in Laravel and set it to *, but it didn’t fix the problem.
In Nuxt, I tried forwarding the X-Forwarded-For header like this:

interceptors: {
  onRequest: (
    _app: NuxtApp,
    ctx: FetchContext,
    _logger: ConsolaInstance,
  ) => {
    const headers = useRequestHeaders();
    ctx.options.headers = {
      ...ctx.options.headers,
      "X-Forwarded-For": headers["x-forwarded-for"],
    };
  },
},

However, this triggers Cloudflare’s security mechanisms, flagging the request as potentially harmful.

Question:
Is there a better way to ensure the real client IP is sent to the backend during the first SSR load? Should I pass the IP in a different header, or is there a configuration I’m missing in Vercel to forward the client’s IP correctly?

Any suggestions are welcome!