Your AI-built app works locally but breaks when you deploy it? Check these 6 things
You built an app with Cursor, Claude Code, Lovable or Bolt. On your laptop it's perfect. You deploy it, and you get a blank page, a 502 , or a login button that spins forever. We run a small deployment platform, so we watch a lot of first deploys. Most of the failures we see happen before the app even starts, and the causes repeat. None of them mean the AI wrote bad code. They're the gap between…
Using AI to build an app works well on your laptop, but deploying it can present challenges. Deployments often result in blank pages, 502 errors, or login buttons that spin indefinitely. Most of these failures occur before the app even begins running, and the root causes are consistent. The AI doesn't resolve the discrepancy between local and server environments. Here are six common issues and their fixes:
1. The frontend still calls localhost. The backend was running on your machine during development, so the code directs the frontend to it. In production, localhost represents the visitor's computer, leading to connection failures. To resolve this, read the API address from configuration and set it according to the environment. Import the environment variable for the API URL and use it in the fetch request.
2. Frontend variables are baked in during the build. ENV_…, NEXT_PUBLIC_…, and REACT_APP_… variables are static at build time. If you modify them on the server after the build, the changes won't be reflected. To address this, set these variables before the build on your hosting platform, then rebuild and redeploy.
3. The server listens on the incorrect address or port. On your laptop, app.listen(5000) works perfectly. However, in production, the app must listen on all interfaces and the port provided by the hosting platform, usually indicated by the PORT variable. If the platform's health check cannot reach the app, deployment may fail or time out. Specify the port using process.env.PORT or 3000, and listen on 0.0.0.0 to accept connections from all interfaces.
4. The database is not transferred to the production environment. Locally, you might have a SQLite file or a Dockerized Postgres with test data. In production, there's an empty database or none at all, and your tables may not exist yet. To fix this, create a production database, set the DATABASE_URL environment variable to it, and run migrations against it, either during deployment or manually using commands like npx prisma migrate deploy or alembic upgrade head.
5. CORS blocks the frontend. The frontend and API may reside on different domains (e.g., app.example.com and api.example.com). The browser prohibits cross-origin resource sharing (CORS) unless the API explicitly allows the frontend's production domain. If you use cookies, list the exact domain instead of using "*". The error may resemble a network failure, which can lead to confusion. Configure the API to allow your frontend's production domain and specify credentials as needed.
6. Secrets end up in the frontend. AI tools sometimes embed service keys or third-party API keys in the frontend code, making them publicly accessible. This practice should be avoided, as anyone can inspect the browser's dev tools to read these secrets. To prevent this, store secrets on the server and call third-party APIs from your backend. If using Supabase, only include the anon key in the frontend, and ensure Row Level Security (RLS) is enabled for every table.
To avoid these issues, perform the following checklist before your first deploy:
- Remove any instances of localhost from the frontend code.
- Set frontend variables before the build process.
- Configure the server to listen on 0.0.0.0 and the appropriate PORT.
- Set DATABASE_URL correctly and run migrations before deployment.
- Configure CORS to allow connections from your production domain.
- Keep all secrets on the server, avoiding frontend exposure.
If your deploy still fails, review the build log from the top, as the first error is typically the root cause.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.
