Skip to content
RIPE NCC member · Local Internet RegistryCall us on 020 3318 3449sales@hosting-telecom.uk

Redirecting to HTTPS

SSL and HTTPS13 min read

How to make your website open only over HTTPS: .htaccess, CMS settings and checking the result.

Contents

A guide to redirecting HTTP to HTTPS so that every visitor to your website gets a secure connection.

Why redirect to HTTPS

Benefits of HTTPS

  • Security – data between the browser and the server is encrypted
  • SEO benefits – Google ranks HTTPS websites higher
  • User trust – the padlock in the browser
  • Modern APIs – many require HTTPS (geolocation, camera and others)
  • HTTP/2 and HTTP/3 – work only over HTTPS
  • No warnings – browsers mark HTTP sites as “Not secure”
Important Before you set up a redirect, make sure your SSL certificate is installed and working!

Checking SSL before you start

Step 1: Make sure SSL is installed

  1. Open your website over HTTPS: https://example.com
  2. Check that there is a padlock in the address bar
  3. Click the padlock → Certificate is valid
  4. Make sure the certificate has not expired

Step 2: Check in cPanel

  1. Go to SSL/TLS Status
  2. Find your domain
  3. The status should be Secure (green tick)

Step 3: Check online

Use these tools:

Ways to set up the redirect

A universal method for Apache servers.

A basic redirect for the whole website

  1. Open File Manager in cPanel
  2. Go to public_html
  3. Find the file .htaccess (turn on “Show Hidden Files”)
  4. If the file does not exist, create it
  5. Add the following at the beginning of the file:
# Redirect the whole website to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Explanation:

  • RewriteEngine On – turns on the rewrite module
  • RewriteCond %{HTTPS} off – checks that the connection is NOT HTTPS
  • RewriteRule ^(.*)$ – applies to all URLs
  • https://%{HTTP_HOST}%{REQUEST_URI} – redirects to the HTTPS version
  • [L,R=301] – the last rule (L) and a permanent redirect (301)

Redirecting to HTTPS with www

If you want everything to redirect to https://www.example.com:

# Redirect to HTTPS with WWW
RewriteEngine On

# First add www if it is missing
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Then redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Redirecting to HTTPS without www

If you want https://example.com (without www):

# Redirect to HTTPS without WWW
RewriteEngine On

# Remove www if present
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [L,R=301]

# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

A universal redirect (always works)

If the basic method does not work, use this alternative:

# Universal HTTPS redirect
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Or using an environment variable:

Via an ENV variable (for some hosts)

RewriteEngine On
RewriteCond %{ENV:HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

For Cloudflare or behind a proxy

If you use Cloudflare or your website is behind a proxy:

# Redirect for Cloudflare
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Excluding specific pages

If you need to exclude some URLs from the redirect:

# HTTPS redirect with exceptions
RewriteEngine On
RewriteCond %{HTTPS} off
# Exclude /api/ and /webhook/
RewriteCond %{REQUEST_URI} !^/api/
RewriteCond %{REQUEST_URI} !^/webhook/
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Method 2: cPanel Redirects

A graphical interface for simple redirects.

Setting up Redirects

  1. Go to Domains → Redirects
  2. Click Create a Redirect
  3. Fill in the form:

Type: Permanent (301)

Domain: select your domain

Directory (optional): leave empty

Redirects to: https://example.com

www. redirection:

  • Redirect with or without www. – redirects both versions
  • Or choose a specific option

Wild Card Redirect: ON (tick the box)

  1. Click Add
Tip The Redirects method is simpler, but .htaccess gives you more control and flexibility.

Method 3: WordPress

Methods specific to WordPress websites.

Via wp-config.php

Add the following to the file wp-config.php before the line /* That's all, stop editing! */:

// Force HTTPS for the whole website
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

// Force HTTPS for the admin area
define('FORCE_SSL_ADMIN', true);

// If behind a proxy (Cloudflare)
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS']='on';
}

Via the theme’s functions.php

Add the following to your theme’s functions.php:

// Redirect to HTTPS
function redirect_to_https() {
    if (!is_ssl()) {
        wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301);
        exit();
    }
}
add_action('template_redirect', 'redirect_to_https');

WordPress plugins

Recommended plugins:

  • Really Simple SSL – sets up HTTPS automatically
  • SSL Insecure Content Fixer – fixes mixed content
  • WP Force SSL – forces HTTPS

Changing the URLs in the database

After setting up the redirect, update the URLs in WordPress:

Via the admin panel:

  1. Settings → General
  2. Change:
  3. Save Changes

Via WP-CLI:

wp search-replace 'http://example.com' 'https://example.com' --dry-run
wp search-replace 'http://example.com' 'https://example.com'

Via SQL (be careful!):

-- Be SURE to take a backup before running this!
UPDATE wp_options SET option_value = REPLACE(option_value, 'http://example.com', 'https://example.com');
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://example.com', 'https://example.com');
UPDATE wp_posts SET guid = REPLACE(guid, 'http://example.com', 'https://example.com');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'http://example.com', 'https://example.com');

Method 4: Other CMSs

Joomla

Via .htaccess: Use the basic .htaccess method (see Method 1)

Via Global Configuration:

  1. System → Global Configuration
  2. Server tab
  3. Force HTTPS: Entire Site
  4. Save & Close

Drupal

Via settings.php:

// Add to settings.php
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
  $_SERVER['HTTPS'] = 'on';
}

Plus the .htaccess redirect (Method 1)

Magento

Via the admin panel:

  1. Stores → Configuration → General → Web
  2. Base URLs (Secure):
    • Secure Base URL: https://example.com/
    • Use Secure URLs on Storefront: Yes
    • Use Secure URLs in Admin: Yes

Plus the .htaccess redirect

OpenCart

Via the configuration files:

Change the following in config.php and admin/config.php:

define('HTTP_SERVER', 'https://example.com/');
define('HTTPS_SERVER', 'https://example.com/');

Checking the redirect

Manual check

  1. Open your browser in a private window
  2. Go to http://example.com (without the S)
  3. It should automatically redirect to https://example.com
  4. Check for the padlock in the address bar

Checking with and without www

Check all the variants:

With curl (command line)

# Check the redirect
curl -I http://example.com

# It should show:
# HTTP/1.1 301 Moved Permanently
# Location: https://example.com/
Check, following redirects automatically

curl -IL http://example.com

It should show a 301, then 200 OK on HTTPS

Online tools

Troubleshooting

Problem: Redirect loop (infinite redirect)

Symptoms:

  • The browser shows “ERR_TOO_MANY_REDIRECTS”
  • The page keeps reloading

Causes:

  1. Conflicting redirect rules
  2. Incorrect configuration on Cloudflare
  3. SSL problems on your hosting

Solution 1: Check .htaccess

# Make sure there are no duplicate rules
# There should be only ONE HTTPS redirect rule

Solution 2: For Cloudflare

  1. Cloudflare → SSL/TLS → Overview
  2. Change the mode to Full (strict) or Full
  3. Do not use Flexible

Solution 3: Temporarily disable the redirect

  1. Rename .htaccess to .htaccess.bak
  2. Check whether HTTPS works directly
  3. Put .htaccess back and fix the rules

Problem: Mixed content

Symptoms:

  • The padlock is crossed out or shows a warning
  • The browser console shows “Mixed Content” warnings

Cause: An HTTPS page loads HTTP resources (images, CSS, JS)

Solution: See the detailed guide: Fixing mixed content in cPanel

A quick fix with .htaccess:

# Automatically upgrades HTTP requests to HTTPS
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Problem: WordPress admin not working

Symptoms:

  • You cannot log in to wp-admin
  • An endless redirect on the login page

Solution: Add this to wp-config.php:

define('FORCE_SSL_ADMIN', true);

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

Problem: Some pages do not redirect

Check:

  1. .htaccess is in the right directory (public_html)
  2. There is no RewriteEngine Off in .htaccess
  3. There are no exceptions for specific pages
  4. The Apache module mod_rewrite is enabled (it usually is by default)

Solution: Add this to the beginning of .htaccess:

# Make sure mod_rewrite is working
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

Problem: The redirect works, but slowly

Cause: A temporary redirect (302) instead of a permanent one (301)

Solution: Make sure you use R=301 in the RewriteRule:

RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
                                                            ^^^^
                                                      Important: 301

Clear your browser cache:

  • Chrome: Ctrl+Shift+Delete → Cached images and files
  • Firefox: Ctrl+Shift+Delete → Cache
  • Safari: Command+Option+E

Problem: API endpoints do not work

Cause: Some APIs must be reachable over HTTP

Solution: Exclude the API from the redirect:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/api/
RewriteCond %{REQUEST_URI} !^/webhook/
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

HSTS (HTTP Strict Transport Security)

After setting up the redirect, add HSTS for stronger security.

What HSTS is

HSTS makes the browser ALWAYS use HTTPS, even if the user types HTTP.

Benefits:

  • Protection against SSL stripping attacks
  • Faster (no HTTP request)
  • Better for SEO

Enabling HSTS

Add this to .htaccess AFTER the redirect:

# HSTS - 1 year (including subdomains)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

Parameters:

  • max-age=31536000 – how long it applies (1 year, in seconds)
  • includeSubDomains – applies to subdomains
  • preload – for inclusion in browsers’ preload list
Warning HSTS cannot easily be undone! Make sure HTTPS works on ALL subdomains before you enable includeSubDomains.

Testing HSTS

In the browser:

  1. Chrome → DevTools (F12) → Network
  2. Refresh the page
  3. Find the Strict-Transport-Security header

With curl:

curl -I https://example.com | grep -i strict

HSTS Preload

For maximum security, add your website to the HSTS Preload List:

  1. Enable HSTS with the preload parameter
  2. Wait a few days
  3. Submit a request at hstspreload.org
  4. Once approved, browsers will ALWAYS use HTTPS
Important Removal from the preload list can take months! Be sure before you add your site.

Full .htaccess configuration

A recommended full configuration for a production website:

# ============================================
# HTTPS redirect and security
# ============================================

# Enable mod_rewrite
<IfModule mod_rewrite.c>
RewriteEngine On

# Basic settings
RewriteBase /

# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Redirect www to non-www (or the other way round - uncomment what you need)
# Without www:
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [L,R=301]

# With www (uncomment if needed):
# RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

</IfModule>

# ============================================
# Security headers
# ============================================

<IfModule mod_headers.c>

# HSTS - force HTTPS (1 year)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

# Prevent MIME-type sniffing
Header always set X-Content-Type-Options "nosniff"

# Protection against clickjacking
Header always set X-Frame-Options "SAMEORIGIN"

# XSS Protection
Header always set X-XSS-Protection "1; mode=block"

# Referrer Policy
Header always set Referrer-Policy "strict-origin-when-cross-origin"

# Content Security Policy (adjust for your website)
# Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"

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

</IfModule>

# ============================================
# Performance
# ============================================

# Compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
</IfModule>

# Caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
</IfModule>

Checklist

Before you start

  • The SSL certificate is installed
  • The website opens over HTTPS
  • There are no certificate errors
  • You have a backup of .htaccess
  • You have a backup of the website

After setting up

  • HTTP redirects to HTTPS
  • www and non-www both work correctly
  • All pages are accessible
  • There is no redirect loop
  • There are no mixed content warnings
  • The admin panel works (if you use a CMS)
  • Forms submit
  • API endpoints work
  • Checked in different browsers
  • The HSTS header is set (optional)

Testing

Best practices

  1. Use a 301 redirect
    • A permanent redirect (301) is better for SEO
    • A temporary one (302) does not pass on link value
  2. Use a single canonical URL
    • Choose one option: with www or without www
    • Redirect all variants to the canonical one
  3. Enable HSTS
    • Once HTTPS is running stably
    • Start with a smaller max-age, then increase it
  4. Fix mixed content
    • All resources should load over HTTPS
    • Use relative URLs
  5. Update sitemap.xml
    • All URLs should start with https://
    • Submit it to Google Search Console
  6. Update your links on social media
    • Facebook, X, Instagram and others
  7. Monitor for errors
    • Check the logs for 404 and 500 errors
    • Set up alerts for certificate problems

Performance

Effect on speed

HTTPS is slightly slower than HTTP because of:

  • The SSL handshake
  • Encryption and decryption

But modern optimisations make up for it:

  • HTTP/2 (works only over HTTPS) – faster than HTTP/1.1
  • TLS 1.3 – a fast handshake
  • Session resumption – reuse of sessions

Optimising HTTPS

  1. Use HTTP/2
    • Usually enabled on modern servers
  2. Enable OCSP Stapling
    • Speeds up certificate checking
    • Configured at server level
  3. Use a CDN
    • Cloudflare, AWS CloudFront
    • They cache content closer to your users
  4. Session Resumption
    • Usually enabled by default

Undoing the redirect

If you need to go back to HTTP temporarily:

Method 1: Rename .htaccess

# Via File Manager or SSH
mv .htaccess .htaccess.disabled

Method 2: Comment out the rules

Open .htaccess and add # before the rules:

# RewriteEngine On
# RewriteCond %{HTTPS} off
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Method 3: Delete it via cPanel Redirects

  1. Domains → Redirects
  2. Find the HTTPS redirect
  3. Click Delete
Warning Do not turn HTTPS off if you have HSTS enabled! It will cause problems for your users.

Migrating from HTTP to HTTPS – checklist

Stage 1: Preparation (a week ahead)

  • An SSL certificate is installed
  • HTTPS access has been tested
  • All subdomains have been checked
  • Backups have been made

Stage 2: Migration (day X)

  • The .htaccess redirect is set up
  • Internal links have been updated
  • Mixed content has been fixed
  • CMS configuration files have been updated

Stage 3: SEO (straight afterwards)

  • sitemap.xml has been updated
  • It has been submitted to Google Search Console
  • robots.txt has been updated (if you have one)
  • Canonical tags have been checked
  • Open Graph tags have been updated

Stage 4: External services

  • URLs on social media have been updated
  • External links have been updated
  • Partners have been told about the change
  • Advertising campaigns have been updated

Stage 5: Monitoring (the first week)

  • Check search rankings
  • Monitor traffic
  • Check the logs for errors
  • Check the SSL expiry date

Stage 6: Optimisation (a month later)

  • HSTS is enabled
  • Performance has been optimised
  • Added to the HSTS Preload List (optional)

See also

Didn’t find the answer? Ask our support team — we’ll help.

Choose which cookies we may use. You can change your mind at any time with the “Cookie settings” link at the bottom of every page.

Necessary

Always active

They keep the site secure and remember your cookie choice. They don’t identify you.

Google Analytics counts visits and shows which pages people find useful, so we can improve the site. Which cookies