[ GF.dev ] All Tools →

How to Find and Fix Mixed Content on Your Website

Published 2026-03-29 · Last modified 2026-03-29

Mixed content is one of the most common issues that surfaces after migrating a site from HTTP to HTTPS. It occurs when an HTTPS page loads sub-resources — images, scripts, stylesheets, fonts, iframes — over plain HTTP. Browsers block mixed active content outright and display warnings for mixed passive content, undermining the trust signal that HTTPS is supposed to provide.

This guide covers how to detect mixed content across an entire site, fix each type systematically, and prevent it from reappearing. Use the GF.dev Mixed Content Test to scan your pages as you work through each step. This article is part of the SSL/TLS Configuration Guide.

Why Mixed Content Matters

When a browser loads an HTTPS page, it establishes a secure TLS connection to protect data in transit. If that page then requests a script over HTTP, an attacker on the network can intercept and modify the script, injecting malicious code that runs with full access to the HTTPS page. This completely defeats the purpose of HTTPS.

Browsers classify mixed content into two categories:

Finding Mixed Content: Four Methods

1. GF.dev Mixed Content Test

The fastest way to scan any public URL is the GF.dev Mixed Content Test. Enter your URL and the tool will load the page, inspect every sub-resource, and report which ones are loaded over HTTP.

2. Browser Developer Tools

Open Chrome DevTools (F12), go to the Console tab, and look for yellow or red warnings containing "Mixed Content". The Network tab can also be filtered by mixed-content:displayed or mixed-content:blockable in the filter bar.

3. Content-Security-Policy Reporting

For site-wide detection, deploy CSP in report-only mode. This tells browsers to report mixed content without blocking anything:

Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-report-endpoint;

Collect reports at your endpoint for a week, then analyze which resources and pages are affected.

4. Command-Line Crawlers

For large sites, use a crawler that checks every page. Tools like mixed-content-scan (Node.js) or custom scripts with wget --spider can automate the process.

Fixing Mixed Content: By Resource Type

Hardcoded HTTP URLs in HTML

The most common cause. Search your templates and content for http:// and replace with https:// or protocol-relative URLs (//example.com/resource). Protocol-relative URLs are falling out of favor; prefer explicit https:// where possible.

# Find hardcoded HTTP URLs in your project
grep -rn 'http://' --include='*.html' --include='*.css' --include='*.js' .

Database-Stored URLs (WordPress, CMS)

Content management systems often store absolute URLs in the database. For WordPress, use WP-CLI:

wp search-replace 'http://example.com' 'https://example.com' --all-tables --dry-run
# Review output, then run without --dry-run

Third-Party Resources

If a third-party CDN or API does not support HTTPS, you have three options:

  1. Switch to a provider that supports HTTPS.
  2. Self-host the resource and serve it over HTTPS.
  3. Use a reverse proxy to fetch the resource over HTTP internally and serve it over HTTPS to your users (not ideal, but functional).

CSS url() References

Stylesheets can contain mixed content via url(http://...) in background images, fonts, and imports. Search all .css files and inline <style> blocks for HTTP URLs.

Inline JavaScript

JavaScript may construct URLs dynamically. Search for patterns like 'http://' + or "http://" + in your scripts and update the logic to use https:// or window.location.protocol.

Preventing Mixed Content from Reappearing

After fixing existing issues, put guardrails in place:

The upgrade-insecure-requests Directive in Detail

This CSP directive is the single most effective mitigation for mixed content. When the browser sees this directive, it rewrites every HTTP sub-resource URL on the page to HTTPS before making the request. This covers images, scripts, stylesheets, fonts, and all other resource types.

# Nginx
add_header Content-Security-Policy "upgrade-insecure-requests" always;

# Apache
Header always set Content-Security-Policy "upgrade-insecure-requests"

Note that this does not fix the underlying URLs — you should still update them — but it provides an immediate safety net.

Once your site is clean, verify your full TLS setup by returning to the SSL/TLS Configuration Guide and running the TLS Scanner.

Try These Tools

Mixed Content Scanner