After turning on SSL and forcing HTTPS, many websites still show a broken padlock, “Not secure” warnings or partially protected pages. The usual culprit is mixed content: your HTML loads over HTTPS, but some images, scripts, styles or iframes are still requested over plain HTTP. Browsers block or downgrade these insecure requests, which can break layouts, disable JavaScript and hurt both user trust and SEO. In hosting migrations we handle at dchost.com, mixed content issues are one of the most common sources of confusion after an otherwise successful HTTPS rollout.
In this guide we will walk through practical ways to fix mixed content and insecure HTTP requests in three real-world scenarios: WordPress sites, custom PHP applications and setups that sit behind a CDN or reverse proxy. We will focus on repeatable methods you can apply across projects, not just one-off hacks. By the end, you should have a clear playbook: how to detect mixed content, how to fix it at the source (database, code, templates), how to configure your web server and CDN, and how to safely enable stricter security headers like HSTS and CSP without breaking your site again.
İçindekiler
- 1 Why HTTPS Breaks Existing Sites: Mixed Content 101
- 2 Step 1 – Detect All Mixed Content and Insecure HTTP Requests
- 3 Fixing Mixed Content in WordPress After Enabling SSL
- 3.1 1. Fix the Core URLs in WordPress Settings
- 3.2 2. Run a Database-Wide HTTP → HTTPS Search & Replace
- 3.3 3. Fix Hard-Coded URLs in Themes, Child Themes and Plugins
- 3.4 4. Page Builders, Widgets and Shortcodes
- 3.5 5. Mixed Content Fixer Plugins – Helpful, But Don’t Stop There
- 3.6 6. Special Cases: WooCommerce and Payments
- 4 Fixing Mixed Content in Custom PHP Applications
- 5 CDN, Reverse Proxy and Mixed Content
- 6 Advanced Tuning: HSTS, CSP and Security Headers After Cleanup
- 7 Hosting and Infrastructure Tips from the dchost.com Team
- 8 Wrapping Up: A Simple Playbook for Mixed Content Cleanup
Why HTTPS Breaks Existing Sites: Mixed Content 101
Mixed content happens when a browser loads a page via HTTPS but finds resources inside that page that still use HTTP. Example: your page is https://example.com, but an image tag points to http://example.com/logo.png. From the browser’s perspective, the secure page is now partially dependent on an insecure connection, which opens the door to tampering and eavesdropping.
Modern browsers treat these cases in two ways:
- Active mixed content (JavaScript, CSS, iframes, XHR/fetch requests) is usually blocked completely. This can break menus, sliders, analytics, payment widgets and more.
- Passive mixed content (images, video, audio) may still load, but the browser shows a “Not fully secure” padlock, which reduces trust and can affect conversion rates.
From an SEO and security standpoint, mixed content is more than a cosmetic warning. It can:
- Prevent you from getting the full ranking benefits of HTTPS and HTTP/2/HTTP/3.
- Block important scripts like A/B testing, analytics or checkout logic.
- Confuse caching and CDN rules, since HTTP and HTTPS URLs may be cached separately.
We covered browser-side symptoms in more depth in our SSL certificate errors guide about mixed content and browser warnings. In this article we will focus on how to actually fix those problems on WordPress, generic PHP apps and CDN-backed setups.
Step 1 – Detect All Mixed Content and Insecure HTTP Requests
Before changing code or running database scripts, you need a reliable inventory of what is still loading over HTTP. Here are the most practical approaches we use when helping customers on our hosting platform.
Browser Developer Tools
Every browser has a built-in console that reports mixed content:
- Open your site in Chrome or Edge.
- Right-click > Inspect > open the Console tab.
- Reload the page over HTTPS.
You will see messages like Mixed Content: The page at 'https://example.com' was loaded over HTTPS, but requested an insecure image 'http://example.com/logo.png'. Note the full URLs and file types – this will guide where you need to fix things (content, theme, plugin, CDN, etc.).
Network Tab and HAR Exports
The Network tab in dev tools lets you filter hard-to-see requests:
- Open Network, check “Preserve log”, then reload.
- Filter by “scheme” or search for
http://in the URL column. - Export as HAR if you want a sharable report.
This is useful for spotting AJAX requests, font files or third-party widgets that still use HTTP.
Search in Code and Database
On WordPress and custom PHP projects, the root cause is almost always hard-coded HTTP URLs in the database or source files.
- File search: Use
grep, your IDE or a code search tool to look forhttp://yourdomain.cominside your theme, plugins and custom PHP files. - Database search: For WordPress, a
wp search-replacevia WP-CLI or a serialized-aware search/replace tool helps find old HTTP URLs inwp_posts,wp_optionsand widget tables.
Always run database changes in dry-run mode first or take a full backup (database + files). Our article on WordPress backup strategies on shared hosting and VPS is a good companion before doing any bulk operations.
Log- and Tool-Based Checks
On VPS or dedicated servers, access logs can also reveal mixed content:
- Filter your web server logs for
"GET http://"or known asset paths. - Use CLI tools like
curlto fetch pages and grep forhttp://.
Once you have a list of insecure URLs, grouping them by pattern (same directory, same plugin, same widget) makes the cleanup much faster.
Fixing Mixed Content in WordPress After Enabling SSL
WordPress is both the easiest and the trickiest platform for mixed content: easy because there are standard settings, tricky because plugins, page builders and serialized data can hide HTTP URLs in many places. Below is the sequence we recommend when customers move their WordPress sites to HTTPS on our shared hosting, VPS or dedicated servers.
1. Fix the Core URLs in WordPress Settings
Start with WordPress’s own idea of your URL:
- Log in to wp-admin.
- Go to Settings > General.
- Update WordPress Address (URL) and Site Address (URL) from
http://example.comtohttps://example.com.
On some managed environments or when using wp-config.php constants like WP_HOME and WP_SITEURL, you may need to update those instead. After this change, new internal links should automatically be generated with HTTPS.
2. Run a Database-Wide HTTP → HTTPS Search & Replace
Existing content (posts, pages, widgets, shortcodes) usually still contains old HTTP URLs. The cleanest long-term solution is a one-time search and replace in the database:
- Use a serialized-aware tool (WP-CLI
wp search-replaceor a trusted migration plugin) to replacehttp://example.comwithhttps://example.com. - Include all core tables (
wp_posts,wp_postmeta,wp_options,wp_terms, etc.) and custom tables created by major plugins. - Run a dry run first to see how many changes will be made, then run the real operation.
This takes care of most images, internal links and embedded media pointing back to your own domain. For more context around redirects and SEO-safe changes, you can compare this step with the move scenarios in our full HTTPS migration guide with 301 redirects and HSTS.
3. Fix Hard-Coded URLs in Themes, Child Themes and Plugins
Many older themes and customizations contain hard-coded URLs in PHP templates, CSS or JavaScript files. Typical places:
header.phporfooter.phplinking tohttp://example.com/style.cssor external fonts.- Custom logo or background URLs in the theme’s options framework stored as HTTP.
- Inline JavaScript that references
http://analytics or tracking endpoints.
Best practice is to avoid hard-coding the protocol. In WordPress PHP templates, use helpers like:
home_url(),site_url()andplugins_url()which are aware of HTTPS.wp_enqueue_style()andwp_enqueue_script()with protocol-agnostic URLs or HTTPS endpoints.
If you maintain custom themes for clients, adding “no hard-coded http://” to your coding standards will save a lot of future debugging.
4. Page Builders, Widgets and Shortcodes
Visual page builders and widget frameworks often store full URLs in their own data structures. After a global search/replace, you may still see mixed content for:
- Background images configured in a page builder’s design panel.
- Button links, icon lists, or “image box” widgets pointing to HTTP.
- Custom HTML widgets with manually typed
http://links.
Approach:
- Identify which pages still show mixed content in the browser console.
- Edit those specific pages in the builder and re-save, ensuring all URLs are HTTPS.
- Search your widgets for any
http://references and update them.
For big sites, this can be a gradual process: fix the most visited pages first (home, product/category pages, landing pages), then work through the rest.
5. Mixed Content Fixer Plugins – Helpful, But Don’t Stop There
There are plugins that scan and rewrite HTTP URLs on the fly to HTTPS using output buffering. We see agencies use them as a quick fix during migrations, and that’s fine as a temporary safety net. However, relying on them permanently has drawbacks:
- Extra processing on every request, which can hurt performance.
- Harder to debug issues when you don’t know whether a URL came from the database or was rewritten dynamically.
- Doesn’t fix the underlying data; any external integration that bypasses WordPress (RSS, API, SEO tools) may still see HTTP URLs.
Our recommendation: use such plugins to catch anything you missed during migration, but still clean your database and code so that the plugin eventually becomes unnecessary.
6. Special Cases: WooCommerce and Payments
E-commerce brings additional mixed content sources:
- Product images or downloadable files referenced with HTTP in old product descriptions.
- Gateway or iframe-based payment methods that load external assets over HTTP.
- Custom checkout scripts or validation endpoints pointing to
http://.
Steps:
- Run search/replace on product descriptions and custom fields.
- Check each payment gateway’s documentation for HTTPS requirements and update any callback URLs.
- Test cart and checkout thoroughly with browser dev tools open to watch for blocked scripts.
For a broader look at how HTTPS interacts with PCI-DSS and hosting choices, see our article on PCI‑DSS-compliant e‑commerce hosting, including SSL, logs and backups.
Fixing Mixed Content in Custom PHP Applications
For Laravel, Symfony and other custom PHP apps (including in-house frameworks), the principles are similar but you have more direct control. At dchost.com, we often see three root causes: base URL configuration, hard-coded asset paths and cookies/sessions not being marked as secure.
1. Centralise and Correct Your Base URL
Most frameworks have a single base URL or “app URL” setting:
- Laravel:
APP_URL=https://example.comin.env. - Symfony: router configuration, framework settings, or trusted proxies settings.
- Custom apps: a config file like
config.phpthat definesBASE_URL.
Make sure this value uses https://, and use that configuration variable everywhere instead of concatenating "http://" strings in templates or controllers. Updating this one place can automatically fix many generated URLs.
2. Asset Helpers and Templating Engines
Use your framework’s asset helpers instead of manual URLs:
- Laravel’s
asset(),url(),route()helpers respect HTTPS if your app is correctly configured. - In Twig/Blade or custom view layers, ensure links are generated with routes, not hard-coded
http://prefixes.
If your app sits behind a reverse proxy or load balancer that terminates SSL, configure trusted proxies so the framework knows the original scheme is HTTPS (e.g. X-Forwarded-Proto: https). Otherwise it may keep generating HTTP URLs even though the user sees HTTPS at the edge.
3. Fix External API and Asset Calls
Many mixed content problems in custom apps come from:
- Loading external JS/CSS libraries from
http://cdn.example.com. - Embedding third-party widgets in iframes with HTTP URLs.
- AJAX calls to unsecured APIs on your own subdomains.
Wherever possible, switch to HTTPS endpoints provided by those third parties. If no HTTPS endpoint exists and the resource is critical, you may need to:
- Host the asset yourself over HTTPS (with license compliance in mind).
- Proxy the request through your own backend that exposes an HTTPS URL.
Remember that browsers increasingly block active mixed content; the workaround of “just ignore it” no longer works.
4. Enforce HTTPS at the Web Server Level
Your app should behave as if HTTPS is the default. Ensure you also enforce it at the web server level:
- Apache (.htaccess): create or update rules to redirect all HTTP traffic to HTTPS with a 301 status.
- Nginx: have a separate server block listening on port 80 that returns a 301 redirect to the HTTPS version.
We go into detail about 301 redirects, canonical URLs and SEO-safe changes in our guide to SEO‑safe URL structure changes with 301 redirects, which pairs nicely with an HTTPS migration.
5. Cookies, Sessions and the Secure Flag
Mixed content is often discussed purely in terms of assets, but cookie security matters too. Once your site runs on HTTPS:
- Set
SecureandHttpOnlyflags on session cookies so they cannot be sent over HTTP. - Use
SameSite=LaxorStrictwhere possible, especially for admin or account areas.
We explored cookie flags and how to configure them in web servers and apps in our guide to SameSite, Secure and HttpOnly cookies. While cookies are not “mixed content” in the classic sense, getting them right is part of the same overall HTTPS hardening process.
CDN, Reverse Proxy and Mixed Content
CDNs and reverse proxies introduce another layer of complexity. A common pattern we see for new dchost.com customers is this:
- Your origin server is still accessible via HTTP (e.g.
http://origin.example.com). - The CDN provides an HTTPS-enabled URL (e.g.
https://www.example.com). - Some assets in your HTML still point directly to the origin with
http://origin.example.com/file.js.
The browser does not care that a CDN is involved – it still sees HTTP vs HTTPS and flags mixed content. To fix this cleanly:
1. Decide the “Source of Truth” for URLs
Pick one canonical domain and scheme for public access, usually https://www.example.com or https://example.com behind the CDN. Then ensure:
- Your application generates URLs pointing to that canonical domain.
- The CDN is configured to fetch from your origin via HTTP or HTTPS as appropriate, but this is invisible to the browser.
Don’t mix public URLs that go directly to the origin and others that go via the CDN unless you have a very specific reason (and even then, keep them all HTTPS).
2. Use HTTPS for CDN Asset URLs
If you use a separate CDN hostname for static files (e.g. static.examplecdn.com):
- Enable an SSL certificate for that CDN hostname.
- Update asset URLs in your app or WordPress plugin settings to use
https://static.examplecdn.comrather thanhttp://. - Avoid protocol-relative URLs (
//static.examplecdn.com) if they cause confusion with proxies or security scanners; explicithttps://is usually clearer.
If you are still deciding whether to introduce a CDN, we explain the trade-offs in our practical CDN decision guide, including traffic patterns and geography.
3. Respect Cache-Control and Invalidation
Once everything is on HTTPS, you want the CDN to cache aggressively to benefit from reduced latency and offloaded traffic. But when cleaning mixed content, you’ll be frequently changing assets. Make sure you:
- Use versioned file names or cache-busting query strings (e.g.
style.css?v=2). - Configure
Cache-ControlandETagheaders correctly so that browsers and CDNs revalidate when necessary. - Know how to purge specific URLs or tags from your CDN cache when you correct mixed content sources.
We explored these headers and their interaction with CDNs in detail in our HTTP cache-control and CDN rules guide for faster sites. After an HTTPS migration, revisiting those rules is a good idea.
Advanced Tuning: HSTS, CSP and Security Headers After Cleanup
Once you have removed mixed content and the site is consistently served over HTTPS, you can safely enable stricter HTTP security headers to harden your setup.
1. HSTS (HTTP Strict Transport Security)
HSTS tells browsers to always use HTTPS for your domain, even if a user or script tries to access it via HTTP. Example header:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Introduce HSTS gradually:
- Start with a small
max-age(e.g. a few minutes or hours) and test thoroughly. - Increase to longer periods (e.g. 6–12 months) once you are confident.
- Only add
preloadand submit to the browser preload list when you are sure there are no HTTP-only endpoints left.
We provide a step-by-step breakdown of HSTS and related headers in our HTTP security headers guide for HSTS, CSP and more.
2. Content Security Policy (CSP) and Mixed Content
CSP lets you explicitly declare which sources are allowed for scripts, styles, images and more. It can also help prevent future mixed content regressions:
- Use
upgrade-insecure-requeststo tell compatible browsers to treathttp://URLs ashttps://where possible. - Use
block-all-mixed-contentto forbid any HTTP resources entirely once you are sure everything is clean.
Start with Content-Security-Policy-Report-Only so you can see what would be blocked before enforcing it in production. This gives you time to adjust external scripts and images without impacting users.
3. Other Helpful Headers
While not directly related to mixed content, it is a good time to set:
X-Frame-Optionsorframe-ancestorsto control framing.Referrer-Policyto limit referrer data leakage.X-Content-Type-Options: nosniffto prevent MIME type sniffing.
These all work best when your site is consistently served over HTTPS. Combining them with a clean mixed-content-free setup significantly raises the barrier for common web attacks.
Hosting and Infrastructure Tips from the dchost.com Team
Many mixed content headaches come from partial or inconsistent HTTPS setups on the hosting side. When you run your site on dchost.com shared hosting, VPS or dedicated servers, we recommend:
- Always enabling SSL on your primary domain and key subdomains, ideally using free and automated certificates so they renew without manual effort.
- Setting automatic HTTP → HTTPS redirects at the web server or control panel level to make HTTPS the only public entry point.
- Using HTTP/2 or HTTP/3 support on your hosting plan to get the performance benefits that make HTTPS migrations feel like an upgrade, not just a security chore.
- Keeping a consistent environment between staging and production so you can catch mixed content in a staging URL before cutting over DNS.
If you do not yet have SSL enabled, start with our guide on why free SSL with Let's Encrypt matters and how to enable it on cPanel and DirectAdmin. That article covers certificate issuance and automation; this one helps you clean up the application side afterward.
Wrapping Up: A Simple Playbook for Mixed Content Cleanup
Fixing mixed content and insecure HTTP requests after enabling SSL is less about magic and more about following a clear sequence. First, detect all HTTP resources via browser dev tools, code/database searches and logs. Second, fix URLs at the source: update WordPress settings and database entries, clean hard-coded URLs in themes and plugins, and centralize base URLs and asset helpers in custom PHP apps. Third, align your hosting and CDN so that everything consistently uses HTTPS from the user’s perspective, with proper redirects, cache rules and CDN hostnames.
Only after the site is clean should you tighten the screws with HSTS, CSP and other security headers to prevent regressions and raise your overall security level. As a hosting team, we see that sites which treat HTTPS as a first-class requirement from day one have far fewer surprises later on. If you are planning a migration to HTTPS or moving your WordPress or PHP application to a new environment, our team at dchost.com can help you choose the right shared hosting, VPS or dedicated server and configure SSL, redirects and security headers correctly from the start.
