Bolt.new: App Works in Preview But Breaks in Production
Why does the same code work in preview and break in production? Because they were never the same system. The preview is Bolt’s environment, stocked with your secrets and your cached packages. Production is a bare host that has none of that until you hand it over yourself.
“I can see the preview working perfectly within Bolt.new… when deployed to the live site… just a blank screen.”
— alanp97 on Netlify Support, 2025
That blank screen has a small set of causes, and they sort in a clear order of likelihood. Work them top to bottom.
Start with environment variables, because that is most of it
Before you touch a line of code, check your environment variables. This alone clears most working-preview, broken-production failures.
Bolt injects your API keys, database strings, and login tokens straight into its own preview. Deploy to Netlify, Vercel, or Render and those secrets do not travel with the code, because secrets are kept out of git on purpose. The host starts empty. Open your host’s project settings, find Environment Variables, then open Bolt’s .env and copy every pair across exactly. Trigger a manual redeploy. In most blank-screen cases the code was always fine; the host just had no credentials to connect with.
If env vars are already correct, here are the other four, weighed honestly so you spend your time on the likely cause, not the dramatic one.
Missing a specific secret in production. The HTML shell loads but no data shows, or the first request to your backend fails. The loud advice is to dig through build logs for syntax errors, which is rarely it. A missing database URL crashes the app on its first data fetch with perfect syntax everywhere. Compare your local .env against the host’s settings line by line. A missing SUPABASE_URL or DATABASE_URL is the single most common blank-screen cause. The alert difference matters here too. Useless: Error: Cannot read properties of undefined (reading 'connect'). Useful: App failed to connect to database, SUPABASE_URL is missing from production environment variables.
A build command mismatch. The deploy log fails with “command not found” or “build failed” before anything goes live. Open package.json. Bolt’s preview runs in a lenient development mode; your host runs npm run build strictly and surfaces errors development quietly ignored. Confirm the host’s build command matches package.json exactly.
Asking Bolt to fix a hosting problem. This one you can make worse. You paste the deploy error back into Bolt and now the preview is broken too.
“When asking Bolt to fix a simple bug or syntax issue, it often rewrites the entire file, breaks your UI/UX structure, and still fails to fix the original problem.”
— Tokhirjon, Product Hunt, 2026
Stop. A missing environment variable is not a code problem, and Bolt can only rewrite code. Hand it a hosting error and it edits your source around the error, breaking things that worked. Hosting gaps get fixed in the host’s settings panel, never in the editor. The same compounding pattern is in Bolt.new Doom Loop, and every one of those full-file rewrites quietly re-reads your whole project and burns through context, which is its own expensive problem covered in bolt.new token limit exceeded.
Your domain blocked at the backend. The app loads visually but network requests fail with a “CORS policy” error in the browser tools. The preview URL was auto-approved by your backend; your custom production domain is a stranger to it until you say otherwise. Open browser dev tools, the Network tab, look for the red requests, then go to your backend (Supabase, Firebase, whatever you use) and add your production domain to allowed origins, full URL including the https://.
A package that lives only in preview. The build fails with “Cannot find module” for something that works fine in the editor. Bolt cached it into the preview container but never wrote it into package.json, so the host, building from that manifest from scratch, never installs it. Add it under dependencies by hand or run npm install [package-name] --save in the Bolt shell, then redeploy.
What none of this catches
Run all of that and the deploy comes back. Your users are in. But notice what just happened to Marcus, who shipped a Bolt SaaS and hit exactly this: production sat blank for hours, and the only reason he found out was that he happened to open the live tab. Nothing told him. He checked by accident. That accidental-discovery pattern, where a vibe-coded app is fully broken and every status light still reads green, is the whole subject of my ai-built app crashed.
So weigh the honest options for never checking by accident again. Refreshing the live URL yourself works, until you sleep, or get busy, or assume a clean deploy is a working one. Bolt’s own status tells you Bolt is up, not whether your specific deploy serves a real page. A plain page-up pinger catches a server that is fully down, but the blank screen here often returns a perfectly healthy response with nothing rendered, so the pinger reads green. Sentry catches errors once you wire in its SDK and learn to read what it shows, which is real work for someone who built with AI to avoid exactly that work. Each closes part of the gap. None closes the one between “deploy looked fine” and “a customer found the blank screen first.” NoCrash watches your live production URL from the outside and tells you in plain language within minutes when it stops serving your app while the preview still looks perfect. Start free at nocrash.io and point it at your production URL. The only question left is the boring one: who finds out first when production goes blank, you or your paying user?