How to make your website open only over HTTPS: .htaccess, CMS settings and checking the result.
Contents
- Why redirect to HTTPS
- Benefits of HTTPS
- Checking SSL before you start
- Step 1: Make sure SSL is installed
- Step 2: Check in cPanel
- Step 3: Check online
- Ways to set up the redirect
- Method 1: .htaccess (recommended)
- A basic redirect for the whole website
- Redirecting to HTTPS with www
- Redirecting to HTTPS without www
- A universal redirect (always works)
- For Cloudflare or behind a proxy
- Excluding specific pages
- Method 2: cPanel Redirects
- Setting up Redirects
- Method 3: WordPress
- Via wp-config.php
- Via the theme’s functions.php
- WordPress plugins
- Changing the URLs in the database
- Method 4: Other CMSs
- Joomla
- Drupal
- Magento
- OpenCart
- Checking the redirect
- Manual check
- Checking with and without www
- With curl (command line)
- Online tools
- Troubleshooting
- Problem: Redirect loop (infinite redirect)
- Problem: Mixed content
- Problem: WordPress admin not working
- Problem: Some pages do not redirect
- Problem: The redirect works, but slowly
- Problem: API endpoints do not work
- HSTS (HTTP Strict Transport Security)
- What HSTS is
- Enabling HSTS
- Testing HSTS
- HSTS Preload
- Full .htaccess configuration
- Checklist
- Before you start
- After setting up
- Testing
- Best practices
- Performance
- Effect on speed
- Optimising HTTPS
- Undoing the redirect
- Method 1: Rename .htaccess
- Method 2: Comment out the rules
- Method 3: Delete it via cPanel Redirects
- Migrating from HTTP to HTTPS – checklist
- Stage 1: Preparation (a week ahead)
- Stage 2: Migration (day X)
- Stage 3: SEO (straight afterwards)
- Stage 4: External services
- Stage 5: Monitoring (the first week)
- Stage 6: Optimisation (a month later)
- See also
- External links
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”
Checking SSL before you start
Step 1: Make sure SSL is installed
- Open your website over HTTPS:
https://example.com - Check that there is a padlock in the address bar
- Click the padlock → Certificate is valid
- Make sure the certificate has not expired
Step 2: Check in cPanel
- Go to SSL/TLS Status
- Find your domain
- The status should be Secure (green tick)
Step 3: Check online
Use these tools:
- SSL Labs – detailed analysis
- Why No Padlock – finds problems
Ways to set up the redirect
Method 1: .htaccess (recommended)
A universal method for Apache servers.
A basic redirect for the whole website
- Open File Manager in cPanel
- Go to
public_html - Find the file
.htaccess(turn on “Show Hidden Files”) - If the file does not exist, create it
- 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 moduleRewriteCond %{HTTPS} off– checks that the connection is NOT HTTPSRewriteRule ^(.*)$– applies to all URLshttps://%{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
- Go to Domains → Redirects
- Click Create a Redirect
- 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)
- Click Add
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:
- Settings → General
- Change:
- WordPress Address (URL):
https://example.com - Site Address (URL):
https://example.com
- WordPress Address (URL):
- 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:
- System → Global Configuration
- Server tab
- Force HTTPS: Entire Site
- 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:
- Stores → Configuration → General → Web
- Base URLs (Secure):
- Secure Base URL:
https://example.com/ - Use Secure URLs on Storefront: Yes
- Use Secure URLs in Admin: Yes
- Secure Base URL:
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
- Open your browser in a private window
- Go to
http://example.com(without the S) - It should automatically redirect to
https://example.com - Check for the padlock in the address bar
Checking with and without www
Check all the variants:
http://example.comhttp://www.example.comhttps://example.com(should stay as it is)https://www.example.com(should stay as it is or redirect, depending on your set-up)
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 HTTPSOnline tools
- Redirect Checker – checks the chain of redirects
- HTTP Status – detailed header check
- HTTP Headers Checker
Troubleshooting
Problem: Redirect loop (infinite redirect)
Symptoms:
- The browser shows “ERR_TOO_MANY_REDIRECTS”
- The page keeps reloading
Causes:
- Conflicting redirect rules
- Incorrect configuration on Cloudflare
- SSL problems on your hosting
Solution 1: Check .htaccess
# Make sure there are no duplicate rules
# There should be only ONE HTTPS redirect ruleSolution 2: For Cloudflare
- Cloudflare → SSL/TLS → Overview
- Change the mode to Full (strict) or Full
- Do not use Flexible
Solution 3: Temporarily disable the redirect
- Rename .htaccess to .htaccess.bak
- Check whether HTTPS works directly
- 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:
- .htaccess is in the right directory (public_html)
- There is no
RewriteEngine Offin .htaccess - There are no exceptions for specific pages
- 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: 301Clear 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 subdomainspreload– for inclusion in browsers’ preload list
Testing HSTS
In the browser:
- Chrome → DevTools (F12) → Network
- Refresh the page
- Find the
Strict-Transport-Securityheader
With curl:
curl -I https://example.com | grep -i strictHSTS Preload
For maximum security, add your website to the HSTS Preload List:
- Enable HSTS with the preload parameter
- Wait a few days
- Submit a request at hstspreload.org
- Once approved, browsers will ALWAYS use HTTPS
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
- http://example.com opens
- http://www.example.com opens
- https://example.com opens
- https://www.example.com opens
- Checked in a private window
- Checked on mobile
- Checked with SSL Labs
- Checked with Why No Padlock
Best practices
- Use a 301 redirect
- A permanent redirect (301) is better for SEO
- A temporary one (302) does not pass on link value
- Use a single canonical URL
- Choose one option: with www or without www
- Redirect all variants to the canonical one
- Enable HSTS
- Once HTTPS is running stably
- Start with a smaller max-age, then increase it
- Fix mixed content
- All resources should load over HTTPS
- Use relative URLs
- Update sitemap.xml
- All URLs should start with https://
- Submit it to Google Search Console
- Update your links on social media
- Facebook, X, Instagram and others
- 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
- Use HTTP/2
- Usually enabled on modern servers
- Enable OCSP Stapling
- Speeds up certificate checking
- Configured at server level
- Use a CDN
- Cloudflare, AWS CloudFront
- They cache content closer to your users
- 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.disabledMethod 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
- Domains → Redirects
- Find the HTTPS redirect
- Click Delete
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
- Installing SSL certificates
- Fixing mixed content
- Optimising HTTPS
- Website security
External links
Didn’t find the answer? Ask our support team — we’ll help.