For the longest time, the Search Engine Journal WordPress website ran on an HTTP connection. We decided to migrate to HTTPS after Google confirmed that websites would not lose rankings when moving from HTTP to HTTPS.
Just recently, Google set July 2018 as the deadline for HTTPS implementation. The company warned publishers that, for any HTTP domains, Chrome will display a “not secure” label in the address bar.
This means migrating to HTTPS is important now more than ever.
In this post, I will share the experience I had from migrating the SEJ website to HTTPS and many other WordPress-based websites I’ve worked on.
I’ll be assuming you have basic WordPress coding skills and have already installed an SSL certificate on your server, since most hosting providers offer that feature with one click.
WordPress Website Structure: An Overview
Before starting, here’s a basic overview of how WordPress websites are structured.
Every WordPress website has the following file structure:
It also has a database where website content is stored.
Prior to migration, you have to back up your website via your hosting provider’s backup functionality. It’s important to have a backup so that you can restore your website in case something goes wrong.
You’ll also need to download the files from your backup to perform search and replace operation on your computer.
Here are helpful links from a few popular hosting providers on how to perform a backup:
What Does It Mean to Migrate From HTTP to HTTPS?
Migrating is a process of replacing any single instance of HTTP resource link pointing to your website or external domains with an HTTPS equivalent.
When an HTTPS website tries to load HTTP resource, it can cause a mixed content issue. To avoid this, you need to make sure that none of the following types of website resources point to an HTTP endpoint:
- Images
- JavaScript files
- CSS files
- Internal URLs used in CSS/JavaScript files
- iframes
- Videos
- Audio
- Form actions
- Fonts
Important: Keep in mind that you’ll only need to check your plugins and theme files. Never touch the core files in the wp-admin and wp-includes folders. They are already HTTPS compatible. Editing them is strictly disallowed. Any change to files in those folders may cause unexpected bugs.
Let’s start the migration process. (To perform the steps below, you may use Notpad++, PhpStorm or other code editors of yours. I use ZendStudio.)
Note: You should always perform the migration in your staging environment (i.e., staging.example.com), then go live after making sure you did everything correctly.
1. Search & Replace in Files
To begin, search for instances of your domain pointing to HTTP URLs of your site.
Use the regex for “www” and without “www” URL cases and search for http:\/\/(www\.)?yourdomain\.com
(Replace yourdomain.com with your actual domain name.) After doing the search on my end, I saw that there are two instances of source files pointing to my domain HTTP endpoint.
Since you already have an SSL certificate installed on your hosting, you can safely replace all your domain links with its HTTPS equivalent.
You need to perform the same in your Plugins folder if you have custom-developed plugins which are not hosted at wordpress.org/plugins.
The best practice is to use WordPress’ built-in functions for getting the home URL – which, in our case, would be get_home_url()."/some2.js"
. This will ensure that the correct source link will always be displayed.
I am just pointing out a worst-case scenario since you may have custom themes or plugins badly developed with hardcodings. It is not a recommended way of programming yet happens quite frequently.
Next, you’ll also have to take care of HTTP resources pointing to external domains.
To do this, you’ll need to search for the string http:// in your Plugins and Active Theme folders (in our case “auto-repair” ) files but as a whole word match (see: Fig. 4).
Here is how it looks in my code editor:
Here’s my search result:
On the right section of the browser tree, we can see all instances of the HTTP resources.
Don’t jump to replace all of them into HTTPS just yet! This is because the external HTTP domain, which the resource is pointing to, may not have an SSL certificate installed and may not support an HTTPS connection.
Fortunately, in our example, the link points to Flickr.com, which has a certificate installed and supports HTTPS connections. For this instance, we can just replace http:// with https://.
For external resources, you need to review each instance manually.
Never bulk replace!
If you bulk replace without checking whether the external domain supports HTTPS connection, you may get broken resources or image issues on your website and it will throw an error when loading the external resource.
The screenshot above shows a real problem. You have to investigate which functionality uses that resource and reprogram it.
The best thing to do would be to just download that file to your server and link to it from your side, which is the better option for images.
However, doing this is not always possible. You either need to re-develop or just get rid of that functionality.
Beside scripts or images src attributes and images you also need to look for any http:// instances of
- Forms actions, example:
<form action="http://example.com/">
you can search for action=”http:// - Fonts/CSS files, example:
<link rel="stylesheet" type="text/css" href="http://example.com/>
you can use this regexp<link * href="http://
for searching.
Assuming you went through all of your files, let’s go forward and fix our database.
2. Search & Replace in the Database
First, you’ll have to download search and replace database tool.
Upload it to your server in a long random folder name (e.g., “replace879846513134984451”) because if someone accidentally finds it, there is a security risk.
If you navigate to yourdomain.com/replace879846513134984451 URL, you will see the following:
In this case, again, you need to replace all your domain HTTP instances with HTTPS since an SSL certificate is installed and your domain supports HTTPS.
I use regexp http:\/\/(www\.)?yourdomain\.com
for “www” (http://www.yourdomain.com) and without (http://yourdomain.com ) URL cases.
This fixes only all HTTP occurrences of URLs pointing to your domain.
If there are images still pointing to an external HTTP domain in your post’s content, you can use a plugin called Import External Images to find and fix them.
Clicking the Import button will start downloading images from the external website to your server and replace external images URLs with your domain HTTPS ones.
(Note: Make sure you’re in your server’s wp-content folder and permission is set to 775 to enable the script to upload your images. Otherwise, it might fail.)
This process is very resource consuming. It may result in blank screen issues when loading; it can even take down your server.
In this case, you can increase your server max_exection_time and memory_limit. This problem usually happens with large websites. In some instances, you will need advanced coding skills to solve these problems.
As a general good practice, I always recommend uploading external images to your server via a media uploader and avoid using external URLs. External images sometimes become broken when the domain that hosts it expires or when the file gets deleted.
Assuming you were able to fix your images, there are still iframes, videos, and audio left.
The first and easiest step you can do is to perform the same search and replace operation (see: Fig. 10) for all well-known video/audio hostings, like YouTube, Vimeo, SoundCloud, etc.
Since they support HTTPS, you can safely replace http:\/\/(www\.)?youtube\.com
with https://www.youtube.com, http:\/\/(www\.)?vimeo\.com
with https://www.vimeo.com etc.
For resources other than the well-known domains, there is no way to import them automatically since they are usually large files. You need to search for those in the database by performing custom SQL query to find and fix them manually.
Here is a code snippet you can run to extract all posts which contains src=”http://”.
global $wpdb; $results = $wpdb->get_results( "SELECT ID FROM ".$wpdb->posts." WHERE ( post_content LIKE '%src=\"http://%' OR post_content LIKE \"%src='http://%\" OR post_content LIKE '%src=http://%' ) AND post_status = 'publish' and post_type = IN('post','page') order by post_date desc", OBJECT ); foreach ( $results as $post ) { echo get_permalink($post->ID).'<br/>';}
(Note: You can add post types to the list IN(‘post’,’page’), separated by commas, in case you want to run this over custom posts types. For example in case of WooCommerce you may add also “product” to scan products content.)
After you run this query you will get a list of all posts that have HTTP source and mixed content issue.
Generally, after you finish it is always good to sanity check and run this query to make sure you didn’t leave any instances with HTTP resources.
Also, it is always good to browse the website for a while manually and check via the Google Chrome Console whether it is clean.
When you are sure everything is done right, the final step is to set up 301 redirects from HTTP URLs to HTTPS.
3. Implement Redirects
If your server runs on Apache, here is the code you can put in your .htaccess file.
Be careful when implementing this step – any mistake in a command can break the website.
Put this code at the most top
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </IfModule>
Alternatively, you can use Easy HTTPS Redirection plugin.
4. Update CDN
If you use a CDN, there should be a URL setting similar to Google Analytics where you can update your website to an HTTPS version.
The migration for each CDN is different and you need to check your CDN provider documents or contact support for details how to do that.
5. Changing URL in Google Analytics
You need to change in Google Analytics “Website’s URL” settings in Admin > Property > Property Settings and Admin > View > View Settings.
6. Resubmit Website in Search Console
Since Google treats http://www.example.com and https://www.example.com as different websites, you have to resubmit your website’s HTTPS version to Google Search Console and claim ownership to this property.
Don’t forget to resubmit your sitemap:
Or your disavow file:
Conclusion
Migrating to HTTPS is not a straightforward move as it may seem initially.
For small websites, it usually takes a few hours to finish; whereas, for old and big websites, it may take days to finish the migration properly.
If your content is old, it most likely contains outdated iframe/audio embeds with HTTP URLs and even flash content.
As a final step closely monitor your website after migration to see if everything runs smoothly and bug-free.
Hopefully this article will help you in the time-consuming process of HTTPS migration.
More HTTPS Resources:
- Google Sets Deadline for HTTPS and Warns Publishers to Upgrade Soon
- HTTP to HTTPS Migration: The Ultimate Stress-Free Guide
- The State of HTTPS in 2017
- What Type of SSL Certificate Does Your Website Need?
Image Credits
Featured Image: Image by Paulo Bobita.
Screenshots taken by Vahan Petrosyan, February 2018.