Once you install an SSL certificate and configure your WordPress site to use HTTPS, there is one remaining gap: the old HTTP URLs still work. A visitor who bookmarked http://example.com years ago, or a link on an external site pointing to the HTTP version, will arrive on an insecure connection. Search engines may index both the HTTP and HTTPS versions as separate pages, splitting link equity and creating duplicate content. The solution is a permanent 301 redirect at the server level that forces all HTTP traffic to the HTTPS equivalent before WordPress even loads. The cleanest place for this redirect is the top of the site’s .htaccess file, before the standard WordPress rewrite block, using Apache’s mod_rewrite module. This ensures the redirect happens at the web server layer with no PHP overhead — faster and more reliable than a WordPress redirect hook. After the redirect is in place, set WordPress Address (URL) and Site Address (URL) to https:// in Settings → General, and update the siteurl and home options if needed.
Problem: Your site has an SSL certificate installed but HTTP URLs still load without redirecting to HTTPS — search engines see duplicate content and users occasionally land on the insecure version.
Solution: Add a mod_rewrite redirect block at the top of .htaccess, above the WordPress rewrite block, that issues a permanent 301 redirect from HTTP to HTTPS for all requests.
Add the following block to the very top of your .htaccess, before the # BEGIN WordPress comment:
# Force HTTPS — add ABOVE the WordPress rewrite block
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# BEGIN WordPress
# (WordPress rewrite rules follow here — do not modify)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
If your site is behind a load balancer or a CDN (such as Cloudflare) that terminates SSL before the request reaches Apache, the %{HTTPS} off condition will always be true even for HTTPS requests — causing a redirect loop. In that case, check the forwarded protocol header instead:
# For sites behind a load balancer or Cloudflare
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
NOTE: A 301 redirect is permanent — browsers and search engines cache it aggressively. Test the redirect in a browser that has never visited the site (or in an incognito window) before treating it as final. If you later need to undo it, cached 301s can persist in browsers for months. Also update siteurl and home in Settings → General (or in wp-config.php with define('WP_HOME', 'https://...')) so all internal WordPress URLs use HTTPS.