Skip to content
CH SCShop classwordpress · intermediate · ~60 min · 6 steps

How to move a WordPress site to a new domain

Change a WordPress site's domain with a serialized-safe search-replace, permanent redirects from the old name, and none of the half-moved weirdness.

August 10, 2026 · by Dane Petersen

A domain change sounds like one setting. It isn’t — WordPress writes its address into thousands of database rows, some of them serialized in a way that breaks if you edit it with a plain find-and-replace. The fix is letting WP-CLI do the replacing, because it understands serialized data and a text editor doesn’t. You’ll need WP-CLI, SSH access, and control of both domains’ DNS.

Take the backup first

One database export with a name that explains itself:

wp db export ../backups/pre-domain-move-$(date +%Y-%m-%d).sql

If that command feels unfamiliar, do the backup lesson first — a domain move is exactly the kind of trip you want a way back from.

Point the new domain at the site

In your host’s panel, add the new domain to the site (usually “add domain” or “alias”), then point the new domain’s DNS at the same server the old one uses. Get an SSL certificate issued for the new name before you switch — most hosts do Let’s Encrypt automatically once DNS resolves. Don’t run the search-replace until https://newdomain.com loads something, even if it’s the site wearing the old name.

Run the dry run

This shows every change without making any:

wp search-replace 'https://olddomain.com' 'https://newdomain.com' \
  --dry-run --all-tables-with-prefix --skip-columns=guid

--all-tables-with-prefix catches plugin tables (WooCommerce, Yoast) that plain mode skips. --skip-columns=guid leaves post GUIDs alone — they’re permanent IDs, not links, and changing them re-sends your whole RSS feed. Read the table of counts it prints. If a number surprises you, look before you leap.

Run it for real

Same command, no --dry-run. Then repeat for the variants that hide in old content — http:// and www:

wp search-replace 'https://olddomain.com' 'https://newdomain.com' --all-tables-with-prefix --skip-columns=guid
wp search-replace 'http://olddomain.com' 'https://newdomain.com' --all-tables-with-prefix --skip-columns=guid
wp search-replace '//www.olddomain.com' '//newdomain.com' --all-tables-with-prefix --skip-columns=guid
wp cache flush

This updates siteurl and home too, so there’s no separate settings step. If WP_HOME or WP_SITEURL are hardcoded in wp-config.php, update those by hand — they override the database.

Redirect the old domain permanently

Keep the old domain registered and 301 everything to its new address, path included, so bookmarks and years of Google links still land. If your host has a redirect feature, use it. On Apache, this in the old domain’s .htaccess does the job:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com$ [NC]
RewriteRule ^(.*)$ https://newdomain.com/$1 [R=301,L]

Hold onto the old domain for at least a year — ideally forever. A lapsed domain that once had traffic gets scooped up fast, and you don’t want your old name pointing at someone else’s casino.

Verify the move stuck

Click through the site on the new domain: front page, a few posts, and the media library — images are where a half-done replace shows first. Log in at https://newdomain.com/wp-login.php. Then visit a deep URL on the old domain and confirm it 301s to the same path on the new one (curl shows it plainly):

curl -sI https://olddomain.com/some-old-post/ | grep -i 'location\|HTTP'

Finally, view source on a page and search for the old domain — zero matches means the move is done, not half-moved. If anything’s wrong, that backup from step one restores in minutes.

That's the lesson. Back to the shop for more — or if this is the chore your organization never gets to,that's literally what we're for.