App works locally but not on Vercel? Fixes for Cursor and AI-built apps
npm run dev works perfectly, then the Vercel deploy fails, shows a 500, or loads with missing data. Production differs from your laptop in a few predictable ways: a clean install, a strict build, Linux file names, serverless functions and its own environment variables. Check them in this order.
- Reproduce the production build locally
- Add every environment variable to Vercel
- Build fails: type, lint and import errors
- 500 errors or "Function invocation failed"
- Blank page or 404 on refresh (Vite/React SPA)
- CORS, mixed content and API URLs
- Auth breaks only in production
- Data is empty in production
- Give Cursor the real error, not "it's broken"
1. Reproduce the production build locally
Run what Vercel runs:
rm -rf node_modules .next dist
npm ci
npm run build
npm start # or: npx vite preview
Most "works locally" bugs show up right here, because dev mode skips type checks, linting and optimizations. Fix it locally, then push.
2. Add every environment variable to Vercel
Your .env.local isn't committed (good), so Vercel doesn't have it. Go to Project → Settings → Environment Variables and add each one for Production (and Preview). Then redeploy; existing deployments don't pick up new values.
- Next.js: only
NEXT_PUBLIC_variables reach the browser, and they are inlined at build time. - Vite: only
VITE_variables reach the browser. - Secrets (Stripe secret, OpenAI, Supabase service_role) must not have those prefixes.
3. Build fails: type, lint and import errors
- Type errors: Next.js fails the build on TypeScript errors that dev mode ignored. Fix them rather than setting
ignoreBuildErrors. - Case-sensitive paths:
@/components/navbarvsNavbar.tsxworks on macOS/Windows and fails on Vercel's Linux. If you only changed a file name's case, git may not have noticed:git mv navbar.tsx Navbar.tsx. - Missing dependency: a package installed globally or only in your node_modules but not in
package.jsongivesModule not found.
4. 500 errors or "Function invocation failed"
Open Deployment → Logs (Runtime Logs) and reproduce the error to see the real stack trace. Usual causes:
- A missing server-side env var (see step 2).
- Code that reads or writes local files (
fs.writeFile, SQLite files, uploads folder). The serverless filesystem is read-only and temporary; use a database or object storage. - Calling
http://localhost:3000/api/...from server code. Call the function directly or use a relative URL on the client. - Function timeouts on long AI calls: stream the response or raise
maxDurationwithin your plan's limit.
5. Blank page or 404 on refresh (Vite/React SPA)
For a Vite single-page app, set the framework preset to Vite, output to dist, and add a vercel.json rewrite so deep links load the app:
{"rewrites":[{"source":"/(.*)","destination":"/index.html"}]}
A blank page with a console error about an env var or undefined points back to step 2.
6. CORS, mixed content and API URLs
Hard-coded http://localhost:8000 API URLs work only on your machine. Move them to an env var. A browser on https:// also blocks calls to http:// APIs (mixed content). If a separate backend rejects the request with a CORS error, add your Vercel domain to its allowed origins.
7. Auth breaks only in production
Login redirects back to localhost, or the session is lost: add your Vercel domain to the auth provider's allowed URLs (Supabase URL Configuration, Clerk/Auth.js allowed origins, Google OAuth redirect URIs) and set NEXTAUTH_URL or the equivalent site URL variable. Remember preview deployments get a different URL each time.
8. Data is empty in production
If the deploy works but shows no data, the production env vars may point at a different database, or row-level security is filtering rows. See Supabase returns an empty array.
9. Give Cursor the real error, not "it's broken"
Paste the exact build or runtime log line into Cursor and ask it to explain the cause before editing. If three attempts haven't fixed it, revert to the last working commit instead of letting it stack more changes on top.
Still stuck? We'll fix it at a flat price.
VibeFix fixes broken Lovable, Bolt, Cursor, Replit and v0 apps. Request a free check first, and we'll tell you what's wrong and which plan fits before you pay. If we can't fix it, you get a full refund.
Already know you need help? Quick Fix, $49 (one bug, 24h) · Standard Rescue, $129 · Deploy-Ready, from $199