lumevel
WorkPricingBlogAboutContact
Let's talk

Studio

WorkPricingAboutContact

Connect

InstagramComing soonFacebookComing soonLinkedInComing soonXComing soonEmail

Legal

Legal noticePrivacy policy
© 2026 Lumevel StudioLimoges, France
lumevel
← Back to the journal
AnalysisPublished on 23 June 2026·Lumevel

Mixed-content warnings are still costing you orders

If your checkout page silently downgrades from HTTPS to HTTP when a customer loads it, the browser does not stay quiet about it. Chrome blocks the offending script or image outright and draws a "Not Secure" notice in the address bar. Firefox shows the gray padlock with a red strike. Safari draws a yellow warning triangle on every form field below the mixed request. None of these are subtle. Each one is a moment a customer decides your site looks risky and leaves.

Mixed-content warnings are still costing you orders

If your checkout page silently downgrades from HTTPS to HTTP when a customer loads it, the browser does not stay quiet about it. Chrome blocks the offending script or image outright and draws a "Not Secure" notice in the address bar. Firefox shows the gray padlock with a red strike. Safari draws a yellow warning triangle on every form field below the mixed request. None of these are subtle. Each one is a moment a customer decides your site looks risky and leaves.

For a small-business site, mixed content is the kind of problem that survives for years because nobody notices it in dev. Pages load. Forms submit. The contact form on the homepage works in five browsers, and the team marks the launch done. Six months later someone links a product image from a third-party CDN over HTTP, or a marketing widget pulls a tracking pixel over an older URL, and the breakage shows up only on the checkout page in a specific browser on a specific day.

What mixed content actually means

A page served over HTTPS is loaded into a "secure context." That context is supposed to stay HTTPS end to end. When any sub-resource (script, image, iframe, stylesheet, font, fetch, even a WebSocket) tries to load over plain HTTP, the browser calls it mixed content. According to MDN's Web security / Mixed content page, this falls into two buckets: passive mixed content (images, video, audio), which most browsers still load with a warning, and active mixed content (scripts, iframes, fetch, stylesheets, fonts), which modern browsers block outright.

The catch is that "passive" is a moving target. Chrome has tightened the rules repeatedly. As of the current Chrome behavior, passive mixed audio and video are also auto-upgraded to HTTPS in many cases, and any image that triggers a navigation is upgraded. The MDN page tracks the per-element-type behavior across Chrome, Firefox, Safari, and Edge because the behavior is genuinely inconsistent between them.

Why "it works in dev" is the wrong test

When your site is brand new and your assets are served from the same origin, mixed content is rare. The breakage shows up later, when:

  • a marketing team embeds a third-party widget that exposes some content over HTTP,
  • a CDN or asset host is migrated and the old HTTP URL is still cached in templates,
  • a custom font is referenced from an external stylesheet with an absolute http:// URL,
  • a legacy tracking pixel hard-codes an old URL.

In every case the dev site works because the offending URLs are not yet wired into the page, or are wired but point to a redirect that the dev environment handles. Production surfaces the conflict.

The W3C Secure Contexts spec is explicit: certain browser APIs (geolocation, service workers, payment request, clipboard) are available only in secure contexts. A mixed-content downgrade can silently disable the parts of your checkout that depend on those APIs, even if the HTTP request itself loaded successfully.

The real cost: trust and conversion

Google's HTTPS transparency report has documented the migration from HTTP to HTTPS for years. As of the report's most recent data, Chrome users spend over 95% of their browsing time on HTTPS. The users who do land on mixed-content pages are an unusual cohort: people who clicked a stale link, opened a saved bookmark, or arrived from an old marketing email. They are not browsers; they are buyers with intent.

Mixed-content warnings cost orders in two ways. First, the visible warning erodes trust at exactly the moment you do not want to erode it. Second, blocked resources break functionality. A blocked script means a form does not submit, a price does not update, a cart counter does not refresh. The user blames the site, not the browser, and a fraction of them abandon.

A useful exercise: load your own checkout page, then open DevTools and look at the Console and Network tabs. Anything in red, anything with "mixed-content" in the warning, anything that 404s because the browser stripped the request, is lost revenue.

A practical checklist to clear mixed content

This is the order we run mixed-content audits in. Most sites have a small handful of repeat offenders, not a long tail.

  1. Crawl the production site with a tool that flags mixed-content requests. The Chrome DevTools Security tab highlights every mixed request on the current page; running it page by page is tedious but accurate. For a full crawl, the deprecated Mixed Content Scan tool and the open-source mixed-content-scan package both still work for one-off audits.
  2. Grep the source for http:// strings, especially in templates. CMS themes and plugin templates are the usual suspects. A regex like ["'\s]http://(?!localhost) against the deployed HTML (not the source code) catches the runtime case.
  3. Force HTTPS for all first-party assets. Every script, image, and stylesheet that you control should be referenced over HTTPS or, better, as a root-relative URL (/assets/...) so the protocol inherits from the page.
  4. Audit third-party widgets. Marketing pixels, chat widgets, analytics scripts, video embeds, social share buttons. Check each one's current documentation for the canonical embed code; older tutorials often show HTTP.
  5. Set a strict Content-Security-Policy with upgrade-insecure-requests and block-all-mixed-content. The first directive rewrites HTTP sub-resource requests to HTTPS at the browser level; the second rejects any that still come in HTTP. Both are cheap and they catch regressions automatically.
  6. Add an HSTS header with includeSubDomains and, after 60 days of clean operation, submit to the HSTS preload list. This forces every sub-resource request to be upgraded before the page even renders, which closes the door on future regressions.

When the warning is on the address bar, not the page

There is a separate category of mixed content that is easy to miss: the form action URL. If your form posts to an absolute http://example.com/contact URL but the page is HTTPS, the form submission will not happen in a modern browser without a click-through warning. Worse, the warning is browser-specific and easy to misread as a generic security prompt. Always use relative form actions, or absolute https:// URLs, in production templates.

What to do if you cannot fully fix it

Some third-party assets will only load over HTTP (rare, but it still exists: a few older analytics providers, some on-prem widgets behind a corporate VPN). You have two options.

First, proxy the asset through your own HTTPS origin. You lose CDN caching, but you gain a clean mixed-content profile. For images, this is often fine because the traffic is small.

Second, if you cannot proxy and cannot upgrade, host the asset yourself. Most of the time the file is small and immutable, so a single static download replaces a third-party dependency entirely.

Mixed content is not glamorous work. It is the kind of audit that lives in a one-off spreadsheet at most agencies. But it is one of the few categories of bug where the cost is measured directly in lost orders, and where the fix is straightforward once you find the offenders.

Sources

  1. Mixed content - Web security | MDN
  2. What is mixed content? - web.dev (Google mirror)
  3. Secure Contexts - W3C
  4. Why HTTPS matters - Google Transparency Report