Bolt.new App Can't Connect to Supabase in Production
When your bolt.new supabase not connecting in production issue leaves your live application showing blank tables, infinite loading spinners, or failed network requests, the problem almost often traces back to three distinct failure points: missing environment variables in your hosting provider, silent Row Level Security (RLS) policies blocking unauthenticated visitors, or a paused Supabase project instance. Because Bolt runs inside an in-browser WebContainer preview, it handles local environment files, session state, and network domains differently than a standalone production build on Vercel, Netlify, or Cloudflare Pages.
Resolving the issue requires systematically isolating whether the browser cannot reach Supabase at all, whether Supabase actively rejects your API key, or whether the database query succeeds technically but returns zero rows due to security rules. This guide walks you through the exact console errors you will see, how to fix your host configuration, and how to verify your production data flow.
The Error Code Decoder: What the Browser Console Tells You
When an application generated by Bolt fails to load data in production, the user interface rarely explains why. A card component might stay empty, or a button click might fail silently. To understand what is broken, open Developer Tools in your browser (right-click anywhere on the page, select Inspect, and click the Console and Network tabs), then refresh the page.
Look for calls directed toward your https://<your-project-ref>.supabase.co domain. The HTTP status code or terminal error string will tell you which layer has failed:
- 401 Unauthorized: Your app reached Supabase, but the request was rejected. This indicates that your public anonymous key (
anon_key) is either missing, truncated, invalid, or passed in an unexpected request header. - 403 Forbidden: The server understood who you are, but the action is forbidden. In Supabase setups, this frequently indicates cross-origin resource sharing failures or API gateway restrictions.
- TypeError: Failed to fetch (or net::ERR_NAME_NOT_RESOLVED): The browser could not complete the HTTP request. This occurs when your Supabase project URL variable evaluates to
undefined, pointing requests to non-existent local routes, or when the Supabase database instance is paused. - HTTP 200 OK with an empty array (
[]): This is the most confusing failure mode for non-technical founders. The network request succeeds, the database answers, but the payload contains no data. This is the hallmark signature of Row Level Security blocking access.
Cause 1: Missing Environment Variables on Your Production Host
In Bolt's web workspace, environment variables are typically defined inside a local .env file or stored in workspace settings. When Bolt generates a project—frequently using Vite and React, Svelte, or Vue—those variables exist locally on the virtual file system. When you export or deploy that codebase to an external hosting platform like Vercel, Netlify, or Cloudflare Pages, your local .env file is deliberately excluded from source control for security reasons.
If you deploy the code without manually configuring your environment variables inside your hosting platform's project dashboard, your compiled JavaScript receives undefined whenever it attempts to initialize the Supabase client.
The Client-Side Prefix Requirement
Frontend frameworks built on bundlers like Vite only expose environment variables to the client browser if they carry a specific prefix. In a standard Vite application, any variable without the VITE_ prefix is omitted during the production build step to prevent server-side secrets from leaking into public client bundles.
Check the file where your Supabase client is initialized (typically src/lib/supabase.ts or src/supabaseClient.js). You will usually see code structured like this:
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
export const supabase = createClient(supabaseUrl, supabaseAnonKey);If your hosting provider has those variables named SUPABASE_URL and SUPABASE_ANON_KEY without the VITE_ prefix, import.meta.env.VITE_SUPABASE_URL evaluates to an empty string or undefined. The Supabase client then fails immediately upon page load.
How to Fix Host Environment Variables
- Log into your host provider (Vercel, Netlify, or Cloudflare Pages).
- Navigate to your project settings and find the Environment Variables section.
- Add
VITE_SUPABASE_URLand paste your project URL (for example,https://xyzcompany.supabase.co). - Add
VITE_SUPABASE_ANON_KEYand paste your publicanonkey from your Supabase API settings. - Crucial step: Trigger a manual redeployment. Because frontend bundlers bake client-side environment variables directly into compiled HTML and JavaScript files at build time, changing an environment variable will not update your live site until you create a fresh deployment.
If you run into persistent hosting build failures or script crashes after exporting your project, our step-by-step walkthrough on fixing broken Bolt applications covers general build and deployment pipeline errors.
Cause 2: Row Level Security (RLS) Silently Blocks Anonymous Reads
Row Level Security is a PostgreSQL engine feature that dictates which users can view, insert, update, or delete specific rows in a database table. In Supabase, RLS is enabled by default on newly created tables. For a comprehensive review of this mechanism, review the Supabase Row Level Security documentation.
This creates a common trap for founders: inside Bolt, you might have generated tables, seeded mock data, or logged in using a test account. When viewing the preview, your session was authenticated, so Supabase returned your data as expected. But when an unauthenticated customer visits your live production domain, the application queries Supabase using the public anon role.
If you have enabled RLS on a table but haven't added a policy allowing public SELECT queries, PostgreSQL does not return an error. Instead, it assumes an unauthenticated visitor is simply not allowed to view any records. It returns an HTTP 200 status code with an empty JSON array ([]). Your app appears broken because there is no data to render, yet your developer console shows no red network errors.
To confirm whether RLS is the culprit behind your missing records, read our in-depth diagnosis of how Supabase RLS blocks production reads.
Configuring a Public Read Policy
If your table contains public data (such as product listings, blog posts, or public directory profiles), you must explicitly permit the anon role to read those rows. In your Supabase dashboard:
- Go to Database > Tables and select your table.
- Click Add Policy under the RLS settings.
- Choose Create a policy from scratch.
- Set the policy command to SELECT and the target role to anon (or public, which covers both unauthenticated and authenticated users).
- Under the
USINGexpression, entertrueif all rows are readable, or specify an expression such asstatus = 'published'. - Save the policy and refresh your production site in an incognito window.
Cause 3: Paused Supabase Free Tier Projects
Supabase operates on a multi-tenant cloud infrastructure where free-tier projects pause automatically after a period of database inactivity (typically 7 days without incoming traffic). If you prototyped your application in Bolt, stepped away for a week to prepare marketing materials, and then shared your production link with early beta testers, your database might be asleep.
When an application tries to communicate with a paused Supabase project, requests to the REST endpoint (/rest/v1/) or Auth endpoints will hang and eventually terminate with a connection timeout or network error (such as 503 Service Unavailable or Failed to fetch). The frontend interface cannot bridge the connection.
Checking Project Status
Visit your Supabase dashboard. If your project has entered a dormant state, a yellow banner will appear at the top of the interface stating that the project is paused. Restoring it requires clicking Restore project, which spins the PostgreSQL container back up within a few minutes.
If your application experiences sudden database drops under traffic spikes rather than dormancy, you may be hitting connection limits. Read our architectural review on resolving Supabase connection pool exhaustion to learn how pooling modes protect small database instances.
Cause 4: Supabase Auth Configuration and CORS in Production
If your application loads public data without issue but breaks during login, signup, or password reset flows, the problem is usually rooted in domain authorization. When Bolt compiles your application inside its browser workspace, requests originate from a temporary origin like https://bolt-project-id.webcontainer-api.io. Supabase often accommodates development environments flexibly, but strict authentication flows require explicit production origin whitelisting.
Updating Site URL and Redirect URLs
When Supabase sends magic links, confirmation emails, or processes third-party OAuth callbacks (such as Google or GitHub sign-in), it checks whether the redirect target is permitted. If your live domain is not explicitly declared, Supabase Auth will block the exchange or redirect users to localhost:3000, stranding your visitors.
- Log into your Supabase dashboard and select your project.
- Navigate to Authentication > URL Configuration. Consult the Supabase redirect URL configuration guide for detailed pattern syntax.
- Set the Site URL to your live canonical production domain (e.g.,
https://myapp.com). - Under Redirect URLs, add all subdomains and preview URLs your app uses, including wildcard paths such as
https://myapp.com/**and any staging branches (e.g.,https://staging.myapp.com/**).
CORS and Custom API Routes
Cross-Origin Resource Sharing (CORS) is a browser mechanism that restricts scripts running in one origin from requesting resources from a different origin unless the receiving server grants permission. For a deeper look at the mechanics, consult the MDN Web Docs on Cross-Origin Resource Sharing.
Supabase's managed REST API automatically provides appropriate CORS headers (Access-Control-Allow-Origin: *) for requests authenticated with your public anon key. However, CORS errors can still occur if:
- Your frontend code attempts to send custom HTTP headers that the Supabase API Gateway does not allow.
- You are calling a custom Supabase Edge Function that fails to handle the HTTP
OPTIONSpreflight check properly. - Your client URL is misspelled (for example, missing
https://), causing the browser to misinterpret the call as a relative path to your hosting server instead of an external call to Supabase.
Verifying the Production Pipeline: A Step-by-Step Checklist
Before assuming your database code is broken, run through this verification checklist to determine whether the issue exists in your browser cache, your hosting configuration, or your database engine:
- Test in a clean Incognito/Private window: Modern browsers aggressively cache API responses and local storage session tokens. A private window ensures you are testing the app as a true first-time anonymous user without leftover credentials from your Bolt editing session.
- Inspect the Network Request Payload: Open DevTools, switch to the Network tab, filter by
Fetch/XHR, and click the failing request to your Supabase domain. Inspect the Headers tab. Confirm that theapikeyrequest header matches theanonkey found in your Supabase project settings, and confirm that the request URL points to your actual project reference (notundefined.supabase.co). - Query the REST API directly via cURL: Bypass your frontend entirely to confirm that Supabase itself is responding. Run this command in your terminal, replacing the placeholders with your actual details:
curl -X GET "https://<your-project-ref>.supabase.co/rest/v1/your_table?select=*" \
-H "apikey: YOUR_SUPABASE_ANON_KEY" \
-H "Authorization: Bearer YOUR_SUPABASE_ANON_KEY"If cURL returns your data correctly, the issue is strictly inside your frontend code (such as how your React components manage asynchronous data fetching or environment variable binding). If cURL returns [], your RLS policy is blocking the anonymous key. If cURL returns a connection error, your project is either paused, misconfigured, or unreachable.
Catching Database Failures Before Your Users Do
Building applications with tools like Bolt has allowed non-technical founders to design and ship functional products at unprecedented speed. However, shipping fast introduces new operational blind spots. When an application runs as a client-side Single Page Application (SPA) on Vercel or Netlify, the web server hosting your HTML file almost often returns an HTTP 200 OK status code—even if the app inside the browser is completely broken because it cannot talk to its database.
Traditional uptime pingers check only whether your main domain answers with a 200 status code. If your Supabase instance pauses, if an expired environment variable corrupts your production bundle, or if an aggressive RLS change prevents data from loading, conventional ping monitors will continue reporting green while your users see empty dashboards.
Protecting a production application requires monitoring the actual delivery of application flows: querying data endpoints, running synthetic checks against user authentication flows, and verifying that database connections remain healthy throughout the day. Nightlamp runs synthetic checks, including magic-link and email-delivery flow monitoring via AgentDraft, ensuring that your full sign-in and data retrieval pipeline works under real-world conditions.
More importantly, non-technical teams do not have time to parse cryptic cloud logs when a live outage strikes. Nightlamp does not auto-remediate infrastructure on its own; a real engineer diagnoses each incident and tells you exactly what to fix. With Nightlamp App Care, our team reviews failures across your hosting layer, DNS configuration, and database connections, delivering plain-English instructions directly to you so you can resolve issues immediately.
Frequently Asked Questions
Why does my Supabase query work in Bolt preview but fail when deployed to Vercel?
Bolt runs your application inside a local virtual browser environment where environment variables and local authentication tokens are readily available. When deploying to a host like Vercel, client-side environment variables (such as VITE_SUPABASE_URL) are not carried over automatically; you must manually configure them in your host's project dashboard and trigger a redeployment. Additionally, Bolt previews often run with developer sessions cached, while a new deployment treats visitors as anonymous users governed by Row Level Security.
What does "Failed to fetch" mean when calling Supabase from a live site?
"Failed to fetch" is a generic browser error indicating that an HTTP network request could not complete. The most common causes are an undefined Supabase URL variable (which causes the app to send requests to an invalid URL), a paused Supabase database instance on the free tier, an ad blocker or privacy extension blocking the call, or an unresolved DNS lookup.
Can I disable Row Level Security to make my Bolt app work quickly?
While disabling RLS on a table will immediately allow your application to read and write data, it is a dangerous practice for production environments. Disabling RLS allows anyone on the internet who inspects your public anon key to read, alter, or delete every row in your database table via Supabase's open REST API. Instead of disabling RLS, configure an explicit SELECT policy that safely allows anonymous or authenticated reads while protecting write permissions.
Why does my live app redirect to localhost after Supabase sign-in?
When you trigger email confirmation links, magic links, or OAuth flows, Supabase checks the redirect destination against its authorized URL list. If your live domain is not defined in your Supabase dashboard under Authentication > URL Configuration, Supabase defaults to the base Site URL, which is frequently set to http://localhost:3000 or http://localhost:5173 during local development in Bolt.
If you are managing a live application and want real engineers watching your availability, email delivery, and production endpoints, explore our monitoring plans at Nightlamp pricing. Every plan includes human-assisted incident diagnostics and a 14-day free trial.