"Mixed Content" error after I publish: my https site calls an http address

Checked on

your live site is served over HTTPS, but your code fetches data from an http:// address: your own API, a backend on a server IP, or a leftover http://localhost. Browsers block those requests. Serve the API over HTTPS and point the app at the https:// URL (best), or proxy it through your host so the browser only talks to your own HTTPS domain. Then rebuild.

Symptoms

  • The page loads, but lists are empty, logins fail or forms don't save, and only on the live site.
  • The browser console shows a message like "Mixed Content: The page at 'https://…' was loaded over HTTPS, but requested an insecure resource/XMLHttpRequest endpoint 'http://…'. This request has been blocked; the content must be served over HTTPS." (wording as quoted in user reports such as Netlify forums and Stack Overflow).
  • It worked on http://localhost during development.
  • Images from http:// URLs still show (browsers upgrade some of those, see below), which makes it more confusing.

Why it happens

MDN defines mixed content as "securely loaded web pages that use resources to be fetched via HTTP or another insecure protocol." Browsers "auto-upgrade image, video, and audio mixed content requests from HTTP to HTTPS, and block insecure requests for all other resource types" (MDN: Mixed content). fetch() and XMLHttpRequest calls, which is how your app talks to its API, are in the blockable group. Requests to a bare IP address aren't upgraded either, even for images.

Common ways it gets into an AI-built app:

  1. A hard-coded API URL such as http://my-server.com/api or http://203.0.113.10:8000.
  2. A leftover http://localhost:3000. On the live site that points at each visitor's own computer, so it can never work. Replit's docs list hard-coded localhost URLs as a top reason deployed apps fail (Replit: Networking and app errors).
  3. An environment variable with http://, for example VITE_API_URL=http://..., baked in at build time (Vite: Env variables).
  4. A backend without HTTPS, such as a VPS or a free-tier service you reach by IP.

Step-by-step fix

1. Find the insecure URL

Open the live site, then DevTools Console. MDN: "check your browser's developer console for mixed content warnings." The warning names the exact http:// URL. Search your code and your host's environment variables for it.

2. Best fix: serve the API over HTTPS and use that URL

  • If the API is on a platform that gives you HTTPS (Supabase, Vercel, Netlify Functions, Replit deployments, Render and so on), switch the URL to https://.
  • If it's your own server, put HTTPS in front of it (a domain plus a certificate) and use https://api.yourdomain.com.
  • Update the environment variable on your host (Vercel, Netlify, Lovable, Bolt) and rebuild. VITE_ and NEXT_PUBLIC_ values are fixed at build time.

3. If the API itself is on your host: use relative URLs

If frontend and backend are the same app, call /api/... instead of a full URL. Replit's docs recommend relative paths for exactly this (Replit: Networking and app errors).

4. If you can't add HTTPS to the API yet: proxy it through your host

The browser then only calls your HTTPS domain, and your host forwards the request server-side.

Netlify (a 200 rule is a rewrite, so the address bar doesn't change) in public/_redirects (Netlify: Rewrites and proxies):

/api/*  https://your-api.example.com/:splat  200

Netlify notes that "Proxy rewrite requests will time out after 26 seconds."

Vercel, in vercel.json (Vercel: Rewrites to external origins):

{
  "rewrites": [
    { "source": "/api/:path*", "destination": "https://your-api.example.com/:path*" }
  ]
}

Then change the frontend to call /api/.... The proxy examples in both hosts' docs use https:// destinations, so test an http:// destination before relying on it. The real fix is still HTTPS on the API.

5. Optional extra step: upgrade-insecure-requests

MDN lists the CSP directive upgrade-insecure-requests, which "upgrades all requests to HTTPS, including blockable mixed content." It only helps if the API actually answers on HTTPS at the same address.

Fix prompt for your AI builder

Paste this into Lovable, Bolt, Cursor, Replit, v0 or whichever tool you build with:

Fix prompt
On my live HTTPS site, API calls are blocked with "Mixed Content ... requested an insecure ... This request has been blocked". Fix only the API URLs:
1. Find every http:// URL and any localhost/127.0.0.1 URL the frontend calls (code, config and env var defaults).
2. Replace them with an env var (VITE_API_URL or NEXT_PUBLIC_API_URL) that I'll set to the https:// address, or with relative /api/... paths if the backend is part of this app.
3. Don't hard-code localhost anywhere in production code.
4. List the env vars I need to set on my host and remind me to rebuild.
Don't change any other logic or UI.

How to confirm it's fixed

  1. Rebuild and redeploy, then open the live site in a private window.
  2. The console shows no Mixed Content warnings.
  3. In DevTools Network, every API request goes to https:// (or to your own domain's /api/...) and returns data.

How to find out sooner next time

Heedza opens your live site in a real browser on a schedule and checks that your landing, signup, login and checkout pages load and show their forms. If a blocked request leaves one of those pages without its form, you get an alert with a screenshot and a fix prompt. It doesn't submit forms, so it won't notice a save that fails after the button is pressed. The free scan reports missing security headers (including HSTS and Content-Security-Policy) and exposed keys on your homepage.

Let Heedza check this for you. Heedza’s online and page check keeps checking that your live home page opens with real content, and that your sign-up, log-in and payment pages still open and show their forms and Pay buttons. It never logs in or fills in forms, so it can’t see errors that only show after that.

Made with Lovable, Bolt, Replit, Cursor or v0? Free for 1 site: start free or see prices.

More questions

Why do my http:// images still load?

Browsers auto-upgrade image, video and audio requests to HTTPS (MDN). Data requests aren't upgraded; they're blocked.

Can I turn the block off?

Not for your visitors. The block happens in each visitor's browser.

It's a CORS error now, not mixed content.

Progress: the request is reaching the server. Now the API has to allow your site's origin. If it's a Supabase Edge Function, see Supabase Edge Function CORS error.

Where this comes from