Mixed Content | Blue Frog Docs

Mixed Content

Diagnose and fix mixed content warnings that compromise HTTPS security and trigger browser warnings

Mixed Content

What This Means

Mixed content occurs when an HTTPS webpage loads resources (images, scripts, stylesheets, iframes) over an insecure HTTP connection. This compromises the security of the entire page, triggers browser warnings, and can cause resources to be blocked entirely.

Types of Mixed Content

Active Mixed Content (Blocked):

  • JavaScript files loaded over HTTP
  • CSS stylesheets loaded over HTTP
  • Fonts loaded over HTTP
  • Iframes loaded over HTTP
  • Result: Browsers block these resources entirely

Passive Mixed Content (Warning):

  • Images loaded over HTTP
  • Audio files loaded over HTTP
  • Video files loaded over HTTP
  • Result: Browsers load but show warnings

Impact on Your Business

Security Compromise:

  • Entire page marked as "Not Secure"
  • Users warned of security risk
  • Man-in-the-middle attack vulnerability
  • Compromised encryption benefits

Broken Functionality:

  • Blocked scripts break features
  • Missing CSS breaks layout
  • Blocked fonts cause display issues
  • Iframes don't load

User Trust:

  • Security warnings damage credibility
  • Users abandon insecure pages
  • Conversion rates plummet
  • Professional image damaged

SEO Impact:

How to Diagnose

Method 1: Chrome DevTools Console

  1. Open your website in Chrome (HTTPS version)
  2. Press F12 to open DevTools
  3. Navigate to "Console" tab
  4. Look for mixed content warnings:
    Mixed Content: The page at 'https://example.com/' was loaded over HTTPS, but requested an insecure image 'http://example.com/image.jpg'. This content should also be served over HTTPS.
    

What to Look For:

  • Yellow warning icon (passive mixed content)
  • Red error icon (active mixed content blocked)
  • Resource URLs starting with http://
  • Number and type of mixed content issues

Method 2: Chrome Security Panel

  1. Open your website
  2. Press F12 to open DevTools
  3. Navigate to "Security" tab
  4. Review "Overview" section
  5. Check "Mixed content" section for details

What to Look For:

  • "This page has mixed content" warning
  • List of insecure resources
  • Type of mixed content (active/passive)
  • Resource URLs

Method 3: Why No Padlock Tool

  1. Visit Why No Padlock
  2. Enter your website URL
  3. Click "Test"
  4. Review list of insecure resources

What to Look For:

  • All HTTP resources listed
  • Resource types (images, scripts, CSS)
  • Source URLs
  • Quick fix suggestions

Method 4: View Page Source

  1. Visit your page (HTTPS version)
  2. Right-click → "View Page Source" (Ctrl+U)
  3. Search for http:// (not https://)
  4. Review each result

What to Look For:

<!-- Mixed content examples -->
<img src="http://example.com/image.jpg">
<script src="http://example.com/script.js"></script>
<link href="http://example.com/style.css" rel="stylesheet">
<iframe src="http://example.com/embed"></iframe>

Method 5: Browser Network Tab

  1. Open Chrome DevTools (F12)
  2. Navigate to "Network" tab
  3. Reload page
  4. Filter by "All" or "Other"
  5. Look for resources with:
    • HTTP protocol
    • "blocked:mixed-content" status

What to Look For:

  • Requests with http:// protocol
  • Blocked or failed requests
  • Status showing mixed content block
  • Resource types affected

General Fixes

Fix 1: Update Resource URLs to HTTPS

Convert HTTP URLs to HTTPS:

  1. Images:

    <!-- Before -->
    <img src="http://example.com/image.jpg" alt="Product">
    
    <!-- After -->
    <img src="https://example.com/image.jpg" alt="Product">
    
  2. Scripts:

    <!-- Before -->
    <script src="http://example.com/script.js"></script>
    
    <!-- After -->
    <script src="https://example.com/script.js"></script>
    
  3. Stylesheets:

    <!-- Before -->
    <link href="http://example.com/style.css" rel="stylesheet">
    
    <!-- After -->
    <link href="https://example.com/style.css" rel="stylesheet">
    
  4. Iframes:

    <!-- Before -->
    <iframe src="http://example.com/embed"></iframe>
    
    <!-- After -->
    <iframe src="https://example.com/embed"></iframe>
    

Fix 2: Use Protocol-Relative URLs

Let browser choose protocol:

  1. Remove protocol prefix:

    <!-- Before -->
    <img src="http://cdn.example.com/image.jpg">
    
    <!-- After - protocol-relative -->
    <img src="//cdn.example.com/image.jpg">
    
  2. Works for both HTTP and HTTPS pages:

    • On HTTPS page: Loads as https://cdn.example.com/image.jpg
    • On HTTP page: Loads as http://cdn.example.com/image.jpg
  3. Apply to all external resources:

    <script src="//ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <link href="//fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
    <img src="//cdn.example.com/logo.png" alt="Logo">
    
  4. Note: Modern best practice is to use HTTPS explicitly

Fix 3: Use Relative URLs for Internal Resources

Best practice for same-domain resources:

  1. Use root-relative URLs:

    <!-- Before - absolute with protocol -->
    <img src="http://example.com/images/product.jpg">
    
    <!-- After - root-relative -->
    <img src="/images/product.jpg">
    
  2. Benefits:

    • Works on both HTTP and HTTPS
    • No protocol specification needed
    • Easier to maintain
    • Works in dev and production
  3. Examples:

    <link href="/css/style.css" rel="stylesheet">
    <script src="/js/script.js"></script>
    <img src="/images/logo.png" alt="Logo">
    

Fix 4: Fix CSS Background Images

Update URLs in stylesheets:

  1. Check CSS files for HTTP URLs:

    /* Before */
    .hero {
      background-image: url('http://example.com/hero.jpg');
    }
    
    /* After */
    .hero {
      background-image: url('https://example.com/hero.jpg');
    }
    
    /* Best - relative URL */
    .hero {
      background-image: url('/images/hero.jpg');
    }
    
  2. Check inline styles:

    <!-- Before -->
    <div style="background-image: url('http://example.com/bg.jpg')"></div>
    
    <!-- After -->
    <div style="background-image: url('/images/bg.jpg')"></div>
    

Fix 5: Fix Third-Party Resources

Ensure external resources use HTTPS:

  1. Google Fonts:

    <!-- Before -->
    <link href="http://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
    
    <!-- After -->
    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
    
  2. CDN Resources:

    <!-- Before -->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    
    <!-- After -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    
  3. Social Media Embeds:

    <!-- Ensure embed codes use HTTPS -->
    <iframe src="https://www.youtube.com/embed/VIDEO_ID"></iframe>
    <iframe src="https://www.facebook.com/plugins/page.php"></iframe>
    
  4. Check if third-party supports HTTPS:

    • Try HTTPS version in browser
    • If not available, find alternative provider
    • Or self-host the resource

Fix 6: Use Content Security Policy Upgrade

Automatically upgrade HTTP to HTTPS:

  1. Add CSP header:

    # Nginx
    add_header Content-Security-Policy "upgrade-insecure-requests";
    
    # Apache .htaccess
    Header always set Content-Security-Policy "upgrade-insecure-requests"
    
  2. Or use meta tag:

    <head>
      <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
    </head>
    
  3. How it works:

    • Browser automatically upgrades HTTP requests to HTTPS
    • Applies to all resources on page
    • Fallback: Block if HTTPS version unavailable
  4. Note: This is a temporary fix - better to fix URLs directly

Fix 7: Fix Dynamic Content and JavaScript

Update JavaScript-generated URLs:

  1. Check JavaScript files:

    // Before
    var img = document.createElement('img');
    img.src = 'http://example.com/image.jpg';
    
    // After
    img.src = 'https://example.com/image.jpg';
    
    // Best - use relative URL
    img.src = '/images/image.jpg';
    
  2. Fix AJAX requests:

    // Before
    fetch('http://api.example.com/data')
    
    // After
    fetch('https://api.example.com/data')
    
    // Or relative
    fetch('/api/data')
    
  3. Update API endpoints:

    // Use HTTPS for all API calls
    const API_URL = 'https://api.example.com';
    
  4. Check third-party scripts:

    • Analytics code
    • Ad scripts
    • Chat widgets
    • Ensure all use HTTPS

Platform-Specific Guides

Detailed implementation instructions for your specific platform:

Platform Troubleshooting Guide
Shopify Shopify Mixed Content Guide
WordPress WordPress Mixed Content Guide
Wix Wix Mixed Content Guide
Squarespace Squarespace Mixed Content Guide
Webflow Webflow Mixed Content Guide

Verification

After fixing mixed content:

  1. Clear browser cache:

    • Hard refresh: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
    • Or clear cache in browser settings
  2. Check Chrome Console:

    • Open DevTools Console
    • Reload page
    • Verify no mixed content warnings
    • Should see green padlock in address bar
  3. Test with Why No Padlock:

    • Run test again
    • Should show "All Clear"
    • No insecure resources listed
  4. Check Security Panel:

    • DevTools → Security tab
    • Should show "Secure connection"
    • No mixed content warnings
  5. Test all pages:

    • Homepage
    • Product/category pages
    • Blog posts
    • Contact forms
    • Checkout (if applicable)
  6. Test in multiple browsers:

    • Chrome
    • Firefox
    • Safari
    • Edge

Common Mistakes

  1. Hardcoded HTTP URLs - Use relative or HTTPS
  2. HTTP in CSS - Check background-image URLs
  3. Third-party embeds - Ensure HTTPS versions
  4. Cached resources - Clear cache after fixing
  5. JavaScript-generated URLs - Update API endpoints
  6. Content in database - Search and replace old URLs
  7. Ignoring passive mixed content - Fix images too
  8. Not testing all pages - Some pages may still have issues
  9. Using HTTP for performance - HTTPS is now faster
  10. Forgetting mobile version - Test responsive/mobile site

Troubleshooting Checklist

  • All images use HTTPS or relative URLs
  • All scripts use HTTPS
  • All stylesheets use HTTPS
  • All iframes use HTTPS
  • CSS background images use HTTPS
  • Font files use HTTPS
  • Third-party resources use HTTPS
  • JavaScript-generated URLs use HTTPS
  • API endpoints use HTTPS
  • Database content updated (if hardcoded URLs)
  • Browser cache cleared
  • No console warnings
  • Padlock appears in address bar
  • Tested all major pages
  • Tested in multiple browsers

Quick Fixes by Resource Type

Images:

<!-- Find and replace in all files -->
<img src="http:// → <img src="https://
<img src="http:// → <img src="//
<img src="http://yoursite.com/ → <img src="/

Scripts:

<script src="http:// → <script src="https://

Stylesheets:

<link href="http:// → <link href="https://

CSS:

url('http:// → url('https://
url("http:// → url("https://

Additional Resources

// SYS.FOOTER