How to (actually) move WordPress to a New Domain (with SSL — without losing SEO)

How do you move WordPress to a new domain? Moving my WordPress site to a new domain gave me a headache, but I’m sure it was worth it. I mean, check out my shiny new domain name! .dev, isn’t it awesome? If this move doesn’t give me a SEO boost, I don’t know what does.

Why did it give me a headache? I wanted to move WordPress using an external domain registrar with 301 redirects, without affecting my Let’s Encrypt SSL-certificates and Google Search Console. And not a tutorial in the world to help me out.

Well, I figured it out and today I’ll share it with you.

How to Move a Let’s Encrypt encrypted WordPress website to a New Domain

When you move WordPress to a new domain, it can be painful. Traumatizing even!

Especially in 2019 when it’s pretty much required to secure your site with a SSL-certificate. Especially when there’s Let’s Encrypt offering free SSL-certificates, which of course you’re gonna use! Especially when SEO is the only thing that counts and you use every tool Google has to offer.

You just didn’t know that was going to make the move harder, did you? Did Google? I sure as hell didn’t.

Did Google have any idea what they unleashed upon the world when they enforced the use of SSL certificates?

I tried, but it wasn’t enough

I started with a tutorial by WP Beginner about ‘How to move WordPress without losing SEO‘. Which got me far, but not far enough. Although it says that it’s recently updated. It’s not. How do I know? Nowadays every website needs SSL encryption. It doesn’t mention anything about SSL certificates and even the Htaccess-redirect mentions http:// instead of https://.

After setting up the 301 redirects I was on my own. I couldn’t notify Google of my change of address, because it couldn’t verify I was the owner of my old domain. Which makes sense; its request was redirected. The same goes for my Let’s Encrypt SSL certificate; the challenge couldn’t be completed, because the server couldn’t be reached — because the request was redirected.

After setting up your 301 redirects, Let’s Encrypt validates your new server, instead of the old ones. Rendering your old domain useless due to this error.

My old domain (without a valid SSL certificate) redirecting to my new domain (with a valid SSL certificate) caused all traffic from organic sources to be presented with a beautiful ‘your connection is not private‘ error. Basically rendering all traffic from Google (or any other search engine) useless.

Through this process I learned a ton of tricks to succesfully move WordPress to another host without losing SEO. Even if you’re using Google Search Console and SSL certificates provided by Let’s Encrypt. Let’s begin.

Before you start to Move WordPress

  1. If your domain is registered at an external registrar (different from where you’re going to be hosting your website’s files and database), make sure your domain’s nameservers are set to the nameservers of the server hosting the files and make sure you’re able to reach your server using your new address.
  2. If you’re domain is registered with the same company, usually linking the domain name to your existing hosting package happens automatically or can be done in a few clicks.
  3. To succesfully redirect your old site to your new site, you’ll need the old install to keep running. So, do not remove its files and do not use the same database for your new domain.

How to Not Lose SEO after moving WordPress Website

The basics are pretty simple. First we copy WordPress, then we move WordPress, then we notify Google:

  1. Copy the files,
  2. Copy the database,
  3. Change the Site and Home URL,
  4. Setup a Let’s Encrypt SSL certificate,
  5. Setup the 301 redirects,
  6. Notify Google of your move,
  7. Change Google Analytics property.

Like I said, these are the basics. But there are a few minor details that deserve discussing. Let’s get into that right now.

1. Copy your Website’s Files

Assuming you’ll host your new site on the same server, you could use the terminal and recursively copy the files by doing this:

cp -R ~/path/to/olddomain.com/ ~/path/to/newdomain.com/

Once completed, navigate to ~/path/to/newdomain.com/ to edit the wp-config.php. Find the section looking like this:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'existing_db_name' );
/** MySQL database username */
define( 'DB_USER', 'existing_db_username' );
/** MySQL database password */
define( 'DB_PASSWORD', 'existing_db_password' );
/** MySQL hostname */
define( 'DB_HOST', 'localhost' ); # Usually localhost
view raw wp-config.php hosted with ❤ by GitHub

And change the value of the DB_NAME constant. This will allow us to create a new database in the next step, using the same DB_USER and DB_PASS as your old website:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'new_db_name' ); # CHANGE THIS!
/** MySQL database username */
define( 'DB_USER', 'existing_db_username' );
/** MySQL database password */
define( 'DB_PASSWORD', 'existing_db_password' );
/** MySQL hostname */
define( 'DB_HOST', 'localhost' ); # Usually localhost
view raw edited-wp-config.php hosted with ❤ by GitHub

2. Copy the Database

Every host offers different ways to duplicate a database. However, if you have access to a terminal, I suggest you install WP CLI as creating a new database will be a matter of a few simple commands:

  • Navigate to ~/path/to/olddomain.com/ and execute wp db export ~/path/to/newdomain.com/backup.sql. After the command is finished, you’re new domain’s folder will contain a backup of your database.
  • Navigate to your new domain’s filesystem and run wp db create to create a new database with the credentials you entered in wp-config.php. Afterwards wp db import ~/path/to/newdomain.com/backup.sql will import your old database to the new one.

3. Changing the Site’s URLs

WordPress saves every URL (including inlinks) in any post you’ve ever written statically. To change all mentions of the old URL, we can use WP CLI.

Enter this in your terminal, after you’ve navigated to your new WordPress install:

wp search-replace 'olddomain.com' 'newdomain.com' --skip-columns=guid

At this point, you should be able to reach your website at the new domain.

4. Install Let’s Encrypt SSL-certificate for your New Domain

All you need to do now is install your Let’s Encrypt SSL-certificate on the server. Every hosting company provides how-to’s or automated setups for this. As there are many ways to do this and it’s impossible for me to cover all of them, I suggest you start here.

5. Setting up 301 Redirects on your Old Domain

After you’ve verified that you can reach your site from your new domain with SSL enabled, it’s time to set up the 301 redirects. This is where the tricky part comes in. Especially if you’re using a Let’s Encrypt SSL certificate for your old domain.

Why? It’s explained in full here. To summarize:

Let’s Encrypt tries to connect to your server and read the key it previously generated. If it finds it, it checks if it’s expired and if so, renews it. This is called the ‘challenge’.

In case of a 301 redirect Let’s Encrypt will never find the key you generated before and instead validate your new server.

This is where WP Beginner drops the ball.

The same goes for sending the moving notice to Google. An address change is all good and well, but you’ll never pass Google’s validation if Google’s verification request is redirected to the new domain.

Usually, setting up a 301 redirect including the request URI looks like this:

RewriteEngine on
# 301 Redirect to New Domain incl. Request URI
RewriteRule ^(.*)$ https://newdomain.com/$1 [R=301,L]
view raw 301-redirect.sh hosted with ❤ by GitHub

But since we want to keep Google’s verification and Let’s Encrypt’s challenge in mind, it’ll look this:

RewriteEngine on
# Exception for Google Verification
RewriteCond %{REQUEST_URI} !^/google-verification-file.html
# Exception Let's Encrypt Challenge
RewriteCond %{REQUEST_URI} !^/.well-known/
# 301 Redirect to New Domain incl. Request URI
RewriteRule ^(.*)$ https://newdomain.com/$1 [R=301,L]

You can safely add the above snippet to the top of your .htaccess file within your webroot. No changes are necessary for the Let’s Encrypt challenge to work, as Let’s Encrypt always uses the /.well-known/ to complete its challenge.

6. Finally; Giving Google a Moving Notice

To submit your address change to Google Search Console, you still need to verify that you’re the owner of the old domain. When working with redirects, the HTML File verification method is the only method we can work with, because then we can add an exception for that request in our .htaccess file.

The filename of Google’s verification file differs per account. To find out yours, follow these steps if you’re using the new version of Search Console. Click here if you’re using the old version.

With each step, choose the HTML File verification method. After following the steps, replace google-verification-file.html with the filename of your verification file within your .htaccess file.

Almost there…

At this point, you’re in the clear. All of your search traffic will be redirected to your new domain.

Eventually Google’s crawler bots will catch up on this and replace the old address with the new one. But this can take a while.

To speed things up, you should notify Google of your website’s move by giving them a moving notice:

GSC: Change of Address

  1. First, add your new domain as a website property. It doesn’t matter which method you choose here,
  2. Go to the old version of Google Search Console,
  3. Select the property from which you want to move,
  4. Click on the cog in the top right of the screen and click ‘Change Of Address‘,
  5. In the screen that follows, go through each step. Due to the redirects and exception we put in place earlier, this should go flawlessly — no headache, yay!
Move WordPress Website to New Domain with Google Search Console

Due to the redirects and exception we put in place earlier, you should be able to pass the 4 validation steps flawlessly. Look at the beautiful green checkmarks!

It will take some time before Google has processed your submission — it’s been 10 days and I’m still waiting. So the final step here would be to be patient

Impatiently waiting while Google is processing change of address.

Be patient till Google has processed your submission. Just don’t go crazy.

7. Change your Google Analytics Property URL

Finally, if you’re a Google Analytics-user (which you probably are) make sure you change the Analytics Property URL to your new domain. Do not create a new property, because this will cause you to lose all your old Analytics data (hint: you don’t want this).

Summary

Today we learned how to succesfully move WordPress to a new domain using WP CLI.

To prevent any loss of SEO, we implemented a Htaccess 301-redirect which includes the Request URI. We implemented exceptions in this 301 redirect to prevent the (old) Let’s Encrypt SSL certificate from expiring.

We added an exception to the 301 redirect to succesfully pass Google Search Console’s verification. This is needed to submit a change of address, which will speed up the indexation process in Google, eventually replacing the old domain with the new one. It’s not easy to move WordPress, but I hope that now it’s clear how it should be done.