Wilde Digital
Guide

Why an app built with Lovable, Bolt, Replit or Cursor works in preview but breaks after deploy

The preview and the deployed app are two different environments that happen to run the same code. A "it worked five minutes ago" failure is very often one of a handful of differences between them. This guide lists the five worth checking first, in order.

AI project rescue scopeAsk a specific question

Last updated . Written by Zack Wilde. Prices quoted are Wilde Digital's own published starting rates as of September 12, 2026; they are not market averages.

The short answer

A builder’s preview supplies things your deployed app has to supply for itself: a development server, environment variables, a proxy to your API, permissive login settings and a forgiving file system. When the app moves to real hosting, whichever of those it silently depended on goes missing, and the failure usually shows up as a blank screen, a request that never returns, or a login that loops.

This is true whichever tool generated the code. Lovable, Bolt, Replit and Cursor work differently — some run your app inside their own preview, Cursor edits code that runs on your own machine — but in every case the place you watched it work is not the place your users reach it. The fix is to find which difference matters, not to prompt the tool to “fix deployment” and hope.

The five differences to check, in order

PreviewVariables setin the builderDev proxyforwards /apiLogin allowspreview URLDeployedVariables on host,then rebuildReal API addressor server functionLive domain inallowed redirects
Top: what a builder preview quietly provides. Bottom: what has to exist on real hosting for the same code to work.
  1. Configuration that only exists in the preview. API keys, database URLs and feature flags set in the builder’s settings are not copied to your host automatically. In a Vite app — the setup many of these tools generate — your own variables reach browser code only if they carry the public prefix — VITE_ by default — and Vite documents that their values are bundled at build time. Set a variable after the build and the deployed app never sees it; rebuild after changing one.
  2. An API address that only works in development. A relative request such as /api/reply can succeed in preview because a development proxy forwards it. Vite’s proxy setting applies to the dev server only. In the deployed build nothing forwards the request, so it reaches your static host and fails.
  3. Deep links with no rewrite rule. A single-page app handles its own routes in the browser. Opening /dashboard directly asks the host for a file that does not exist. On Netlify, for example, the documented fix is a /* /index.html 200 rewrite; without a rule like it, the home page loads but a bookmarked app route with no matching file returns 404.
  4. Login redirect settings still pointing at the preview. Authentication providers only send users back to addresses you have allowed. Supabase, a common backend for these builders, documents a default Site URL of http://localhost:3000 that should be changed to the production address. If the live domain is not in the allowed list, sign-in fails or lands somewhere else.
  5. Differences the preview tolerated. File names whose capitalisation does not match their imports work on case-insensitive file systems and fail on a case-sensitive build server. A different Node version, a missing build step or a server function that times out on the host can each break a build that looked finished.

Check these against the deployed app, not the preview. The preview is the one environment guaranteed to look fine.

The fix that makes it worse

The quickest way to make a broken API call “work” is to put the secret key into browser code. It will work, and the key is then readable by anyone who opens the page source or the network panel. Vite’s own documentation warns that VITE_ variables should not contain sensitive information such as API keys.

The durable fix is a server-side boundary — a serverless function or small backend that holds the key and makes the call — with limits on who can call it and how much they can send. If an AI tool proposes moving a key into the client to fix a deploy error, treat that as the moment to stop prompting.

Find the failure yourself in fifteen minutes

  1. Open the deployed app in a private window, with the browser’s developer tools open on the Console and Network tabs.
  2. Repeat the one journey that fails. Note the first red error and the first request that returns an error status or never completes.
  3. Look at that request’s address. If it points at localhost, a preview domain or a relative path your host does not serve, it is difference one or two.
  4. Reload a page other than the home page. A 404 there is difference three.
  5. Sign out and sign in again on the live address. A loop or a redirect to the wrong site is difference four.
  6. Compare the variable names set in the builder with those set on your host. Anything present in one and missing in the other is a candidate.

Write down what you saw, including the exact error text. That record is worth more to whoever fixes it than a description of what the app is supposed to do.

What this looked like in a real inspection

Wilde Digital’s AI project rescue page describes a read-only inspection of an anonymized React, Vite and Express application. One of its eight findings was exactly difference two: the client could fall back to a relative endpoint that worked through a development proxy, while the packaged build was given no real API address. A second finding was the trap in the previous section — the obvious connectivity fix would have made an unprotected paid endpoint easier to reach, so the inspection put the server boundary first.

That inspection read the source; it did not run a build or a server, so its findings are reported as source-supported rather than reproduced. The distinction matters: a deploy failure is confirmed by watching it fail on the host, not by reading the code that probably causes it.

If the failure is not obvious after the checks above, an inspection is $1,500 USD per agreed inspection, with repairs scoped separately afterwards. Whether to repair the app at all is its own question, covered in how to tell whether a vibe-coded app should be repaired or replaced.

Common questions

Is this a problem with Lovable, Bolt, Replit or Cursor specifically?

Not usually. The causes are differences between a development environment and a hosted one, and they apply to hand-written code too. The tools make it easier to reach a working preview without ever configuring the production side, which is why the gap shows up later and all at once.

Why does it work when I deploy from the builder but not from my own host?

The builder’s own deployment carries its own settings, such as stored variables and routing defaults. A different host starts with none of them. List what the builder configured for you, then set the same things on the new host and rebuild.

Can I just ask the AI tool to fix the deployment?

You can, and for a single missing variable it may work. The risk is that it fixes the symptom — for example by moving a secret into browser code or removing an error message — without fixing the cause. Check the deployed result yourself after every change rather than trusting the summary of what was changed.

How do I know which of the five it is?

Use the browser developer tools on the deployed app. The first failing request and the first console error usually point straight at one of them. If they do not, that is the point where reading the source and the hosting configuration together is worth paying for.

Want this applied to your business?

Send the site and the problem. You get an honest read on what is worth doing first, whether or not it is something Wilde Digital sells.

Start an inquiryAI project rescue scope