Moving your site to the HTTPS protocol: the procedure and the redirects

Moving from HTTP to HTTPS is a migration in its own right: every URL changes protocol. Certificate, internal links, redirects with or without www, rule order and tests: the full procedure.

Moving your site to the HTTPS protocol: the procedure and the redirects

HTTPS is the encrypted version of the HTTP protocol. It has become the norm: Chrome and Firefox flag HTTP pages as "Not secure", visitors hesitate to enter their details there, and Google takes HTTPS into account in its rankings.

Moving a site to HTTPS is a migration in its own right. The domain name does not change, but the protocol of every URL does, and Google treats http:// and https:// as two different addresses: every page must be redirected to its HTTPS equivalent, in a single hop. This article gives the procedure, then the redirect rules, with or without www, and the order in which to write them. For the other side, the visitor's, see how to recognise a secure site.

Why move to HTTPS

HTTPS provides three guarantees:

  • confidentiality: exchanges between the browser and the server are encrypted; on public Wi-Fi, nobody can read a password or a card number;
  • integrity: pages and data cannot be altered in transit;
  • authentication: the certificate attests that the site really belongs to that domain name.

Chrome no longer shows a "Secure" label for HTTPS sites: it is the other way round, HTTP pages carry a "Not secure" label, which turns red as soon as data is entered. HTTPS is also a ranking signal for Google, a modest one: it does not replace relevant content.

The procedure in five steps

1. Obtain and install a certificate

Most hosts provide a free Let's Encrypt certificate, activated from the customer area and renewed automatically. For a paid certificate, the procedure goes through a CSR (certificate signing request), generated on the server: it contains the public key and the domain name to certify, and it is what you send to the certificate authority. Here again, the host usually takes care of it.

There are three validation levels: domain only (DV), organisation (OV) and extended validation (EV), which checks the company's identity in more detail. All of them encrypt in the same way, and browsers have no longer distinguished EV certificates in the address bar since 2019. Check that the certificate covers every variant served: exemple.fr and www.exemple.fr, and any subdomains.

2. Switch links and resources to HTTPS

Before the switch, replace http:// addresses with https:// wherever the site writes them: internal links in content, menus, canonical and hreflang tags, sitemap, structured data. Resources loaded by the pages (images, scripts, stylesheets, fonts) must also be in HTTPS: otherwise the browser reports mixed content, and may block the resource.

On WordPress, update the "WordPress Address" and "Site Address" in the general settings, then replace the old addresses in the database with a search and replace tool that respects serialised data (WP-CLI search-replace, for example). Also review the settings of plugins that store addresses, and the sitemap address in robots.txt.

3. Redirect every HTTP URL to its HTTPS equivalent

There is no need to redirect pages one by one: only the protocol changes, so one rule in the server configuration is enough for every URL, path included. It is a 301, permanent redirect: it tells Google to replace the old address with the new one in its index, and it takes visitors who kept an HTTP bookmark to the right page. The rules, with or without www, and their order are detailed below.

4. Update Search Console

A "Domain" property already covers every variant, HTTP and HTTPS. Otherwise, add your site's https:// property (with or without www, whichever will be canonical), then submit the HTTPS sitemap to it. Google will discover the new addresses faster, and you will follow their indexing in the pages report.

5. Test, then monitor

Check the certificate (valid, on every host variant), the absence of mixed content, and above all the redirects: every old address must answer with a single 301 to its final address. Then monitor indexing and traffic over the following weeks; if they drop, check the redirects and the certificate first.

Redirecting HTTP to HTTPS, with or without www

The same page can answer under four addresses: http://exemple.fr, http://www.exemple.fr, https://exemple.fr and https://www.exemple.fr. Choose one, the canonical version (here, HTTPS with www), and redirect the other three to it, in a single hop and with the same path.

The most common mistake is to write two rules that follow each other: one that switches to HTTPS, another that adds the www. http://exemple.fr/page then goes to https://exemple.fr/page, then to https://www.exemple.fr/page: two redirects instead of one, slower for the visitor and for Google. The choice between www and no www is covered in our article on the www redirect.

With Apache

In the .htaccess file at the root of the site, or in the server configuration:

RewriteEngine On

# Any address in http, or on a host other than www.exemple.fr, goes in one redirect to https://www.exemple.fr, same path
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.exemple\.fr$ [NC]
RewriteRule ^ https://www.exemple.fr%{REQUEST_URI} [L,R=301]

The two conditions are joined by [OR]: the rule applies if the request arrives in HTTP, or on a host other than the canonical one, and it sends straight to the final address. Behind a CDN or a load balancer that terminates HTTPS, the server receives every request in HTTP: %{HTTPS} is then always off, and it is the X-Forwarded-Proto header that must be tested, or you get a redirect loop.

With Nginx

One server block for HTTP, another for HTTPS without www, the site itself being served by the https://www.exemple.fr block:

# http, with or without www: to https://www.exemple.fr, same path
server {
    listen 80;
    server_name exemple.fr www.exemple.fr;
    return 301 https://www.exemple.fr$request_uri;
}

# https without www: to https://www.exemple.fr (the certificate must cover exemple.fr)
server {
    listen 443 ssl;
    server_name exemple.fr;
    return 301 https://www.exemple.fr$request_uri;
}

Rule order: specific redirects first

When the move to HTTPS comes with a redesign, URLs change too: the server then carries two kinds of rules. Specific redirects, one per URL, are the redirect plan: this old page to that new page. Generic rules apply to a whole set of addresses: the move to HTTPS, adding the www, a whole directory moved.

Apache reads the rules in order and stops at the first one that redirects. If the generic rule comes first, http://exemple.fr/ancienne-page.html first goes to https://www.exemple.fr/ancienne-page.html, then a second request finds the specific redirect to /nouvelle-page: a chain of two redirects, and an intermediate step that does not exist. So put the specific redirects first, with the full final address (protocol and host included), then the pattern rules, then the generic rules:

RewriteEngine On

# 1. Specific redirects, URL by URL (the redirect plan), to the full final address
RewriteRule "^/?ancienne-page\.html$" "https://www.exemple.fr/nouvelle-page" [L,R=301,NC,QSD,NE]
RewriteRule "^/?categorie/produit-42$" "https://www.exemple.fr/boutique/produit-42" [L,R=301,NC,QSD,NE]

# 2. Pattern rules (a whole directory)
RewriteRule ^actualites/(.*)$ https://www.exemple.fr/blog/$1 [L,R=301]

# 3. Generic rules: http to https, host without www to www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.exemple\.fr$ [NC]
RewriteRule ^ https://www.exemple.fr%{REQUEST_URI} [L,R=301]

This way, the old HTTP address leads in a single hop to the new HTTPS address; addresses without a specific redirect go through the generic rule. The same logic applies between a pattern rule and the exceptions it covers: the exception first.

With Nginx, a return written directly in the server block runs before any location block: specific redirects placed in location blocks would never be read for HTTP requests. Look them up before the generic rule, for example with a map:

# In the http context: the specific redirects, path by path
map $uri $nouvelle_adresse {
    default "";
    /ancienne-page.html /nouvelle-page;
    /categorie/produit-42 /boutique/produit-42;
}

server {
    listen 80;
    server_name exemple.fr www.exemple.fr;
    # Specific redirects first, the generic rule next (same test in the 443 block)
    if ($nouvelle_adresse) {
        return 301 https://www.exemple.fr$nouvelle_adresse;
    }
    return 301 https://www.exemple.fr$request_uri;
}

The .htaccess file exported by Swan contains only specific redirects, one per URL, to the full address on the production (or test) domain, protocol and host included: put them before your generic rules. It contains no HTTPS rule, which is still to be written in the site's configuration. To decide where to keep these rules, see where to put your redirect plan.

To check that an old address leads to its destination in a single hop, request it in HTTP: the answer must be a 301 whose Location header is the final HTTPS address.

curl -sI http://exemple.fr/ancienne-page.html

HTTP/1.1 301 Moved Permanently
Location: https://www.exemple.fr/nouvelle-page

If Location points to an intermediate address (the same page in HTTPS, or the host without www), a generic rule comes before the specific redirect. The SEO risks of a redirect chain are covered in our article on the SEO risks of redirects.

Moving to HTTPS and redesigning at the same time? Swan prepares the redirect plan URL by URL, exports the specific rules and checks every redirect before the switch.

Read next

All posts