Moving a site from HTTP to HTTPS is almost always worth doing, and for most sites it is a short job. The certificate is the easy part. The time goes on the details: an image hard-coded with an old address in a 2014 blog post, a payment callback that still points at the plain version, a redirect that takes three hops where it should take one.
This guide goes in the order I would do it on a real site, with the commands to check each step. It assumes you can edit your site's settings and, for the redirect, either a control panel or an .htaccess or server config file. If your host has a one-click option for any step, use it, then verify the result with the commands below.
Budget an afternoon for a small site, and a planned slot with a rollback plan for anything that takes money or logins. Nothing here is risky if you work in order and test as you go.
1. Get a certificate that covers every name
Most hosts issue free certificates automatically through ACME, the protocol used by Let's Encrypt and several other authorities. Whichever route you take, make sure the certificate covers the bare domain and the www name. A certificate for www.example.com alone will give visitors a warning when they arrive at example.com, and the other way round.
Install it, then check it by typing the HTTPS address into a browser. Do this before touching anything else. If the padlock is missing now, you want to know before you have changed any settings. From a terminal you can see exactly what the server presents:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
Look at the dates and the subject. If you are using a managed WordPress or similar platform, the certificate may take a few minutes to appear after you request it, because validation has to complete first. If DNS for the domain points at an old server, validation will fail, so check dig +short example.com returns the address you expect.
2. Change the site address
Your application has its own idea of its address, and it needs to be told. In WordPress, go to Settings, General, and change both the WordPress Address and the Site Address to start with https://. If you cannot reach the admin area, the same two values live in the wp_options table as siteurl and home, and can be overridden in wp-config.php:
define('WP_HOME', 'https://example.com');
define('WP_SITEURL', 'https://example.com');
Other systems have an equivalent: a base URL in a config file, an environment variable, or a setting in the admin panel. Look for the word "base", "root" or "site URL". Change it, clear any application cache, and reload.
Decide at this point whether the canonical form is example.com or www.example.com. You should already have one preferred form; the migration is the wrong moment to change it. Pick one, use it everywhere, and redirect the other to it.
3. Find and fix mixed content
Mixed content is what you get when an HTTPS page loads something over plain HTTP. Browsers block active content such as scripts and frames outright, and they warn about or upgrade images and other passive content, so the page looks half-broken or loses its padlock.
There are two places old addresses hide: the database (post content, widget settings, theme options) and files (theme templates, custom CSS, JavaScript). Start in the browser. Open the developer console on a few key pages and read the messages; each one names the offending URL.
For the database, use a tool that understands serialised data. In WordPress that means WP-CLI rather than a raw SQL replace, which corrupts serialised arrays by changing string lengths:
wp search-replace 'http://example.com' 'https://example.com' --dry-run
wp search-replace 'http://example.com' 'https://example.com' --skip-columns=guid
Always run the dry run first and take a database backup before the real one. For files, a recursive search finds what is left:
grep -rn "http://example.com" wp-content/themes/ wp-content/plugins/ | head -50
Third-party resources need the same treatment. A script from another provider almost always has an HTTPS version; change the address in your theme. If a resource really exists only over HTTP, that is a reason to replace it, not to leave the page insecure.
4. Redirect, once, with a 301
Now send every HTTP request to HTTPS. Use a permanent 301 redirect, do it in a single hop, and do it for every hostname variant: http://example.com, http://www.example.com, and the HTTPS version of whichever one you are not using as canonical. On Apache, this is the usual shape:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]
On Nginx, a separate server block listening on port 80 with return 301 https://example.com$request_uri; does the job. If you would rather not write rules by hand, the redirect generator produces them for common servers, and the status code reference explains why 301 and not 302.
Test every variant, following redirects, and count the hops:
curl -sIL http://example.com/ | grep -iE '^(HTTP|location)'
curl -sIL http://www.example.com/some-page/ | grep -iE '^(HTTP|location)'
You want one 301 with a Location header, then a 200. If you see two or three, merge the rules. If you see the same address repeated, you have a loop, and the usual cause is a proxy or CDN terminating HTTPS in front of a server that thinks the request is still plain HTTP. In that case the server must read the X-Forwarded-Proto header rather than test HTTPS directly.
5. Update everything that mentions the old address
The redirect catches visitors. It does not fix places that hold the old address. Go through this list and change what applies:
- The XML sitemap and
robots.txt(theSitemap:line) - Canonical tags, Open Graph tags and hreflang annotations
- Analytics and tag manager settings, including the default URL on the property
- Payment provider callbacks, webhooks and API allow-lists
- OAuth redirect URIs for "log in with" buttons
- Social profile links, directory listings and your Google Business entry
- Email signatures and printed material, as they come up for reprinting
Payment and login callbacks deserve special care, because they fail without any visible symptom on the page. A provider that posts a webhook to the HTTP address will receive a redirect, and many will not follow it, so orders stop being marked as paid. Run a test transaction.
6. Tell the search tools
Add the HTTPS version as a new property in your search console, submit the new sitemap, and keep the old property for a few weeks so you can watch for errors. Rankings usually settle within days to a few weeks. A short wobble is normal; a long drop means redirects or canonicals are wrong, so go back to step 4 and check a sample of deep URLs, not just the home page.
7. Add HSTS, carefully and late
HSTS is a response header that tells a browser to use HTTPS for your domain without even trying HTTP first. It closes the small gap where the first request of a visit goes out in plain text before being redirected. It also removes your ability to back out quickly, because browsers remember it for as long as you told them to.
Strict-Transport-Security: max-age=300
Start with a tiny lifetime like the five minutes above, confirm nothing breaks, then raise it to a day, a week, a month and eventually a year. Be careful with includeSubDomains: it applies to every subdomain, including the forgotten one that still runs a plain HTTP admin tool. Leave out preload unless you fully understand that it is very hard to undo.