Skip to content

Guides

Bolt.new works in preview but not on Netlify

Niall Hackett ·

When a Bolt.new app works in the preview but is blank or broken on Netlify, the cause is almost always something Bolt's preview gave you that Netlify doesn't have: your environment variables, the right build settings, or a backend that knows your new domain. Open the live site's browser console first, because the error there tells you which one it is. Then fix it in Netlify and trigger a fresh deploy, since a Vite app bakes its settings in at build time.

Why does my Bolt app work in preview but not when deployed?

Bolt's preview runs your project in a StackBlitz WebContainer inside your browser tab, with Bolt's own copy of your .env. Netlify builds the project from scratch on its own servers, and it doesn't read .env files during the build (Netlify build environment variables). So anything the preview quietly supplied has to be set up again on Netlify.

This comes up constantly. A Netlify forum thread titled "Getting Blank Page On Live Site - Working in Preview In Bolt.New" has several Bolt users with the same blank screen, and a r/boltnewbuilders roundup lists "works in preview, broken in production" as one of the five most common Bolt breaks, usually down to a missing env variable.

Which error do I have?

Open the live site, press F12, and look at the Console tab. Match what you see:

Console errorLikely causeFix section below
supabaseUrl is required or Supabase URL: undefinedEnv vars missing at build timeEnvironment variables
Failed to load module script ... MIME type of "application/octet-stream"You deployed source files, not the buildBuild settings
Blank page, no errors, index.html is nearly emptyWrong publish directoryBuild settings
Build fails in the Netlify deploy logNode version or dependency mismatchNode version
Page loads, but login or API calls failBackend doesn't allow your Netlify domainAuth and allowed origins
Home page works, other pages 404 on refreshMissing SPA redirect404 on refresh

How do I add my Bolt environment variables to Netlify?

This is the most common cause. In one Netlify forum thread, a Bolt app showed a blank page with:

text
Supabase URL: undefined
Supabase Anon Key: undefined
Uncaught Error: supabaseUrl is required.

The app works in Bolt because Bolt has your .env. Netlify doesn't. Copy the exact names from Bolt's .env file, which for a Vite app with Supabase usually look like this:

Shell
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=eyJ...

Add each one in Netlify under Site configuration → Environment variables (Netlify's Bolt guide), or import them all with the Netlify CLI:

Shell
npx netlify-cli env:import .env

Three things trip people up here:

  1. The prefix matters. Vite only exposes variables that start with VITE_ to your frontend (Vite env docs). A variable called SUPABASE_URL will be undefined in the browser even if it's set on Netlify.
  2. You must redeploy after adding them. Vite writes the values into your JavaScript during the build, so the old deploy keeps the undefined values. In Netlify, go to Deploys → Trigger deploy → Clear cache and deploy site.
  3. The variable's scope must include Builds if your Netlify plan lets you set scopes (Netlify env vars with frameworks).

To confirm the build actually saw the variable, temporarily change your build command so the deploy log prints whether it's set, without printing the value:

Shell
# Netlify build command, temporary
[ -n "$VITE_SUPABASE_URL" ] && echo "VITE_SUPABASE_URL is set" || echo "VITE_SUPABASE_URL is MISSING"; npm run build

Only public values belong in VITE_ variables. The Supabase anon or publishable key is fine there because Row Level Security protects your data; a service_role or secret key is not. If one of those is in your .env with a VITE_ prefix, read Supabase service role key exposed before you deploy.

What build settings should a Bolt app use on Netlify?

For a typical Bolt project (Vite + React), Netlify needs to run the build and publish the output folder, not your source files:

toml
# netlify.toml (in the project root)
[build]
  command = "npm run build"
  publish = "dist"

If you see Expected a JavaScript module script but the server responded with a MIME type of "application/octet-stream", you've deployed the raw project. That's what happened in the blank page thread: the user downloaded the project and dragged the whole folder into Netlify. Drag and drop doesn't run a build, so you have to build first and drop only the output (Netlify's Bolt guide):

Shell
npm install
npm run build
# Then drag the dist/ folder (not the project folder) onto app.netlify.com/drop

Two notes on manual deploys. Vite writes to dist/, while Create React App writes to build/, so check which folder your project produced. And because the build runs on your machine, your local .env is what gets baked in, so make sure it has the production values.

Why does the build fail on Netlify when it worked in Bolt?

Bolt runs on Node inside a StackBlitz WebContainer, which can be a different Node version from Netlify's build image (Netlify's Bolt guide). Pin the version so Netlify matches what your project expects. Either add a .nvmrc file to the project root:

text
20

or set a NODE_VERSION environment variable in Netlify. Both override the Node version picked in Netlify's UI (Netlify dependency docs). Also avoid setting NODE_ENV=production on Netlify: it stops devDependencies from installing, and Vite itself is usually a dev dependency.

If the build still fails after that, retry with Clear cache and deploy site and read the first red error in the deploy log, not the last one.

Why does login or my API break only on the live site?

If the page loads but sign-in, OAuth or API calls fail, your backend probably still only knows about Bolt's preview address. Netlify's guide calls this out: look for an API that only accepted requests from Bolt's preview domain, and update its allowed origins (Netlify's Bolt guide).

For Supabase Auth, add your Netlify URL in Authentication → URL Configuration: set the Site URL and add redirect URLs for the live domain (Supabase redirect URLs), for example:

text
https://your-site.netlify.app/**
https://www.yourdomain.com/**

If your code hardcodes a redirect, make it follow whatever domain the app is running on:

TypeScript
await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: { redirectTo: `${window.location.origin}/auth/callback` },
})

More detail is in Supabase login works locally but not live, and if the console shows Failed to fetch or a CORS error, see Lovable "Failed to fetch" / CORS error after deploy, which applies to Bolt apps too.

Why do my pages 404 when I refresh on Netlify?

Your app handles routing in the browser, but Netlify looks for a real file at /dashboard and doesn't find one. Add a public/_redirects file so every path falls back to index.html (Vite copies it into dist/):

text
/*    /index.html   200

Can I switch a Bolt project from Bolt hosting to Netlify?

Not the same project, once it's published. Bolt's Hosting Provider dropdown only appears while a project is unpublished and your Netlify account is connected (Bolt's Netlify docs), and Netlify notes that after publishing to Bolt hosting you'd need a fresh copy to move to Netlify. Duplicating or forking a project also drops the Netlify connection, and reconnecting creates a new Netlify site, so you'll need to point your custom domain at the new one (Bolt publishing issues).

FAQ

I added the environment variables on Netlify but still get supabaseUrl is required. Why?

Either the name doesn't start with VITE_, it doesn't exactly match what your code reads (check import.meta.env. in src/), or you haven't rebuilt since adding it. Use Clear cache and deploy site after any change.

Is it safe to put my Supabase key in Netlify's environment variables if it ends up in the JavaScript?

For the anon or publishable key, yes. It's designed to be public, and Row Level Security is what protects your tables. Never put a service_role or secret key in a VITE_ variable.

Does Netlify Drop use my environment variables?

No. Drop deploys the files you give it without running a build, so whatever was in your local .env when you ran npm run build is what ships.

Bolt's Publish button says it worked, but the site is blank. Is that a Bolt or a Netlify problem?

Usually neither: it's a missing variable or setting in the deployed build. Check the browser console, then the Netlify deploy log. If Bolt fails to publish at all, Bolt's docs suggest building and deploying manually instead (Bolt publishing issues).

Which Node version should I use?

Pick a current LTS version that your dependencies support, pin it with .nvmrc or NODE_VERSION, and keep it the same everywhere you build.


Not sure what else differs between your preview and your live site? ReplayWatch runs a free scan of your deployed AI-built app. It checks that the page actually loads, looks for secrets exposed in your HTML and JavaScript, tests for public Supabase or Firebase reads, reviews security headers, finds broken links and assets, checks your SEO tags, and confirms your signup page is reachable. It can then keep monitoring the site, so the next deploy that goes blank gets caught before your users notice.