DEV Community

MrLong
MrLong

Posted on AI-assisted

Vercel /api works in production but returns 404 in Vite? Here's my local fix

I was testing a Vue 3 + Supabase + Stripe flow locally. The frontend loaded and signup worked, but clicking Upgrade returned a 404 for /api/create-checkout-session.

The endpoint worked on Vercel. The mismatch was the local runtime: vite dev serves the frontend and HMR, but it does not execute files in Vercel's /api directory.

There are two reasonable fixes:

  • Run vercel dev and use Vercel's local runtime.
  • Run a small Node server for the API handlers, then proxy /api from Vite to that server.

I chose the second option so local testing uses the same handler files as deployment. The request path is:

Browser → Vite :5173 → /api proxy → local Node shim :5175 → same handler

The Vite proxy is small:

server: {
  proxy: {
    '/api': {
      target: 'http://localhost:5175',
      changeOrigin: true,
    },
  },
},
Enter fullscreen mode Exit fullscreen mode

The shim routes known paths to the actual handler modules. It adapts Node request/response objects to the shape those handlers expect, rather than maintaining a second copy of checkout or webhook logic.

Two details took longer to catch than the proxy itself:

  1. Load .env before importing handlers. The handlers read Stripe and Supabase variables at module load time, so loading .env afterward is too late.
  2. Preserve the webhook's raw request body. Stripe signature verification uses the original bytes; parsing and re-serializing the body can invalidate an otherwise correct signature.

I run the frontend and API shim separately:

npm run dev
npm run dev:api
Enter fullscreen mode Exit fullscreen mode

Then I test checkout with Stripe test mode and confirm the webhook updates the Supabase subscription row. The live demo is also a sandbox and does not charge a real card.

I wrote up the implementation and tradeoffs in this step-by-step guide.

The Vue 3 + Supabase + Stripe source kit includes the local API shim and notes. It is a separate one-time $29 purchase; the live demo is only a test-mode sandbox.

Disclosure: AI assistance was used to prepare this wording; the project and implementation are mine.

Top comments (0)