← Blog

Bolt.new Env Variables Missing at Build Time: The Fix

If your app works flawlessly in the Bolt preview but breaks the moment you push to production, your bolt.new environment variables not working issue almost often comes down to Vite's static build process. When you build a modern client-side frontend, environment variables are evaluated and baked directly into your JavaScript files when the build command runs, meaning variables added after deployment or named without the required client prefix will resolve to undefined .

For non-technical founders and vibe-coders building production apps on platforms like Bolt.new, Lovable, and Replit, this breakdown is jarring. Your application connects to Supabase, Stripe, or an AI provider inside the in-browser development environment without a hitch. Yet once deployed to hosting providers like Netlify or Vercel, screens turn blank, authentication requests fail, and buttons freeze. Let's walk through the exact mechanics behind why this happens, how to configure each hosting platform, and how to verify your bundle safely before paying customers notice an outage.

Why Bolt.new Environment Variables Fail in Production

To fix the issue permanently, it helps to understand what Bolt.new actually creates under the hood. Most web applications generated by Bolt use Vite's build tooling paired with React, Vue, or Svelte. In a traditional backend server written in Node.js or Python, environment variables live in the server's operating system memory. Whenever a user visits a page, the server dynamically reads process.env.DATABASE_URL on the fly.

Client-side single-page applications do not work like that. Browsers do not have access to your hosting provider's operating system environment. To make values available to code running on an end-user's laptop or smartphone, the bundler performs a find-and-replace routine during the compilation step (npm run build or vite build). If Vite encounters the string import.meta.env.VITE_SUPABASE_URL while compiling your code, it literally replaces that code with your actual URL string, such as "https://xyzcompany.supabase.co".

This architecture introduces two primary failure points that cause bolt.new environment variables not working errors:

  1. The variable was missing when the builder executed: If you trigger a deploy on Netlify or Vercel before pasting your environment variables into the host's settings panel, Vite compiles your bundle with undefined. Adding the variables afterward does nothing to the already-built static HTML and JS files until you trigger a completely fresh deployment.
  2. The variable lacks the mandatory prefix: For security reasons, Vite refuses to expose any variable to the client bundle unless its name starts with VITE_. If you name your key SUPABASE_ANON_KEY instead of VITE_SUPABASE_ANON_KEY, Vite ignores it during the build, leaving the client code stranded.

If you have encountered similar silent failures across other AI development tools, this pattern is nearly identical to our breakdown of Lovable environment variables missing after publish. Both engines rely heavily on static Vite build pipelines.

The VITE_ Prefix: Why Browser Code Ignores Plain Variable Names

Non-technical founders frequently ask why platforms enforce prefixes like VITE_, NEXT_PUBLIC_, or REACT_APP_. This rule exists as a safety barrier to prevent catastrophic security leaks.

When you build software, your environment often contains database passwords, private encryption keys, and third-party webhook secrets. If Vite bundled every environment variable present on your machine or hosting container into the client files, anyone visiting your website could right-click, open Developer Tools, and view your most sensitive credentials. To eliminate this risk, Vite establishes an explicit opt-in convention: only keys prefixed with VITE_ are embedded into the client-facing JavaScript bundle.

// ❌ This will be undefined in the browser bundle:
const apiKey = import.meta.env.STRIPE_SECRET_KEY;

// ❌ This will also be undefined, because Vite does not read plain process.env in the client:
const backendUrl = process.env.API_URL;

// ✅ This will successfully compile into the client bundle:
const publicUrl = import.meta.env.VITE_SUPABASE_URL;
const anonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

If your Bolt project is generating an error stating that an API client cannot initialize because a token is missing, inspect the file where that client is declared. If the code attempts to read a key without VITE_, you must update both the code and your hosting dashboard to use the prefix.

Netlify, Vercel, and Bolt Hosting: Managing Settings Separately

One of the most common traps for founders occurs when transitioning from Bolt's internal sandbox to external hosting. When you click "Deploy" inside Bolt.new, you may be deploying to Bolt's built-in hosting, or exporting directly to GitHub and connecting to Netlify or Vercel. Setting an environment variable in one place does not synchronize it to another.

1. Setting Variables in Bolt.new Built-In Hosting

If you are previewing or publishing inside the Bolt interface, Bolt maintains its own secret store. Check the project settings or sidebar within your workspace to confirm that your .env file or Bolt secrets panel contains every required value. Remember that if you push your code to GitHub, your .env file is typically ignored by Git (via .gitignore) to prevent secrets from being committed to source control. This means your external host receives none of those values by default.

2. Setting Variables in Netlify

According to Netlify's official environment configuration guide, build-time variables must be declared in the site settings before a build starts. Follow these steps:

  • Log in to your Netlify dashboard and select your site.
  • Navigate to Site configuration > Environment variables.
  • Click Add a variable. Enter the key name (e.g., VITE_SUPABASE_URL) and its corresponding value.
  • Select which deploy contexts can access the variable (ensure Production and Deploy Previews are checked).
  • Crucial step: Navigate to the Deploys tab, click Trigger deploy, and select Clear cache and deploy site. If you skip this rebuild, your live site will continue serving the old files containing undefined.

3. Setting Variables in Vercel

As documented in Vercel's environment variables documentation, Vercel exposes variables to the build environment only when explicitly assigned to target environments:

  • Go to your Vercel project dashboard.
  • Click on Settings > Environment Variables.
  • Input the Key (e.g., VITE_BACKEND_API_URL) and the Value.
  • Check the boxes for Production, Preview, and Development.
  • Click Save.
  • Navigate to the Deployments tab, click the three dots next to your current deployment, and select Redeploy . Make sure you do not uncheck "Use existing build cache" if you want a clean compilation.

If you have redeployed and your application still will not load, read through our detailed troubleshooting walkthrough for when your Bolt app is broken in production to rule out dependency mismatches or broken router scripts.

How to Safely Check for Undefined Variables

When you are staring at a blank screen or a cryptic console error like Uncaught TypeError: Cannot read properties of undefined, you need a deterministic way to verify whether your variables made it into the production build without exposing private credentials to the world.

Method 1: Print Variable Presence (Never the Values) at Build Time

You can add a small sanity-check script to your project's vite.config.ts or an initial script file. Instead of printing the raw secrets into the build logs (where third parties or team members might see them), print whether the variable exists as a boolean:

// In your vite.config.ts or a pre-build check:
const requiredVars = ['VITE_SUPABASE_URL', 'VITE_SUPABASE_ANON_KEY', 'VITE_STRIPE_PUBLIC_KEY'];

console.log('--- Checking Build Environment Variables ---');
requiredVars.forEach((varName) => {
  const isSet = Boolean(process.env[varName]);
  console.log(`${varName}: ${isSet ? 'EXISTS' : 'MISSING'}`);
});
console.log('--------------------------------------------');

When Netlify or Vercel builds your project, inspect the deployment logs. If any required variable reports MISSING, you know immediately that your host configuration has not taken effect or the variable name contains a typo.

Method 2: Inspect the Compiled Production Bundle

You can also check whether your variable resolved properly by examining your live website in Google Chrome or Mozilla Firefox:

  1. Open your deployed site in the browser.
  2. Press F12 or right-click anywhere and choose Inspect to open Developer Tools.
  3. Switch to the Console tab and look for errors mentioning supabaseUrl is required or invalid API key.
  4. Go to the Sources (or Debugger) tab, press Ctrl+P (or Cmd+P on Mac), and type the name of your main entry chunk (often starting with index- or main-).
  5. Search the file for your expected configuration string or look for instances where the SDK initialization receives void 0 (the compiled equivalent of undefined). If you see createClient(void 0, void 0), your environment variables were completely absent when the host ran vite build.

Critical Security Rule: What Never Belongs in a Client-Side App

When fixing bolt.new environment variables not working, founders sometimes make an understandable but dangerous mistake: prefixing private backend credentials with VITE_ to "make the error go away."

You must rarely, under any circumstances, place secret backend keys into client-side environment variables. Any variable prefixed with VITE_ is compiled directly into plaintext JavaScript files accessible to anyone visiting your website.

  • Safe for VITE_ prefix (Public): Supabase Project URL, Supabase Anon Key (protected by Row Level Security), Firebase Public API Key, Stripe Publishable Key (pk_live_...), PostHog Project Token.
  • rarely prefix with VITE_ (Private Secrets): Stripe Secret Key ( sk_live_... ), OpenAI Secret Key ( sk-... ), Supabase Service Role Key (which bypasses all Row Level Security), Resend/SendGrid API Keys, Database connection strings containing passwords.

If your Bolt.new application needs to charge a card using a Stripe Secret Key or call the OpenAI API with a private token, that operation cannot happen directly inside the browser component. You must route that request through an edge function (such as Supabase Edge Functions, Netlify Functions, or Vercel Serverless Functions) or a dedicated backend service. The secret key stays on the server, while the client frontend calls the endpoint securely using standard authentication.

Catching Missing Variables Before Your Customers Do

The most frustrating aspect of build-time variable failures is that your deployment pipeline will almost often report a green "Success" checkmark. Hosting providers do not know whether an undefined variable is an intentional fallback or a catastrophic misconfiguration. Netlify and Vercel will happily build a blank page, publish it to your custom domain, and return a 200 OK status code on the homepage.

A basic uptime ping that simply checks if your homepage returns a 200 OK will rarely catch this failure. The HTML shell loads fine, but the JavaScript bundle crashes immediately after mounting. To protect your revenue and user trust, you need a post-deployment verification workflow that actually executes the critical paths powered by those environment variables.

Implement these safeguards to prevent silent breakage:

  • Add runtime guard assertions: In your initialization modules (e.g., where Supabase or Firebase is configured), throw an explicit runtime error if the variable is missing rather than letting the failure cascade silently down your UI tree:
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

if (!supabaseUrl || !supabaseAnonKey) {
  throw new Error('Fatal: Supabase environment variables are missing from the build. Check your hosting dashboard.');
}
  • Synthetic flow monitoring: Run synthetic end-to-end checks against your production deployment that attempt to perform a real user action—such as loading the login modal, requesting a magic link, or fetching a public catalog item. If an environment variable is missing, the synthetic check fails immediately, notifying you before customer complaints start rolling in.

When you run a live product with paying customers and no in-house DevOps engineer, diagnosing whether an outage stems from a missing environment variable, an expired SSL certificate, or a broken third-party webhook can cost hours of stressful guessing. With Nightlamp managed monitoring and App Care, real engineers diagnose each incident and tell you exactly what to fix in plain English. Nightlamp runs synthetic checks, including magic-link and email-delivery flow monitoring via AgentDraft, while keeping continuous watch over your HTTP uptime, DNS records, and certificates so you rarely have to guess what broke.

Frequently Asked Questions

Why did my Bolt.new app work in the editor but fail when deployed?

Inside the Bolt.new editor, variables are supplied dynamically within the browser container workspace. When you deploy to a production host like Netlify or Vercel, the application undergoes a static build step. If your environment variables are not configured in your host's settings before that build runs, Vite compiles the app with undefined values, breaking features that worked in the preview.

Can I just name my variables anything in Bolt.new?

No. Bolt.new projects typically rely on Vite. Vite strictly ignores any environment variable that does not start with the VITE_ prefix for client-side security reasons. If your variable is named API_URL instead of VITE_API_URL, the bundler will not expose it to your browser code.

I updated my environment variables in Netlify/Vercel, but my site is still broken. Why?

Because Vite bakes environment variables into the static JavaScript files during the build phase, updating variables in your hosting dashboard does not retroactively change existing deployed files. You must trigger a manual redeployment (or clear build cache and redeploy) so the builder can recompile your application with the new values.

Is it safe to store my OpenAI API key in a VITE_ variable?

No. Any variable starting with VITE_ is compiled into publicly accessible JavaScript files. Anyone visiting your app can open their browser's Developer Tools and extract your key. Private keys like OpenAI or Stripe secret keys must be kept in backend servers or serverless edge functions.

How can I verify what environment variables my live app is actually seeing?

Open your browser's Developer Tools ( F12 ), switch to the Console tab, and type console.log(import.meta.env) in your source code or inspect your compiled network chunks in the Sources panel. rarely log sensitive production credentials to public consoles; instead, check whether the required keys return a defined string rather than undefined .

Stop losing paying customers to silent production failures and missing configuration keys. Explore our transparent pricing and start your 14-day free trial at Nightlamp pricing to let experienced engineers watch your live web applications around the clock.