
How to move your website to a new domain without losing SEO?
To move your website to a new domain without losing SEO, keep the site's content and URL structure the same, map every old URL to its exact equivalent on the new domain, and set up page-to-page 301 redirects on the old domain. Then verify both domains in Google Search Console, submit the Change of Address request, update internal links, canonical tags and sitemaps to the new domain, and keep the old domain registered and redirecting for at least a year, ideally permanently. A short dip in traffic during the switch is normal, but with complete one-to-one redirects most sites recover their rankings within weeks to a few months.
Changing domains is one of the riskiest SEO projects because every page, link and ranking signal is tied to the old address. This guide walks through the full process: planning, building the redirect map, configuring redirects in Nginx, Apache and Cloudflare, testing them with scripts, telling search engines about the move, monitoring the results and avoiding the mistakes that cause lasting traffic losses.
Why Domain Changes Put SEO at Risk
Search engines index URLs, not businesses. When you move from old-example.com to example.com, every page you've built up rankings for gets a new address. Search engines need to discover the new URLs, connect them to the old ones and transfer the accumulated signals, such as backlinks, from one to the other.
A 301 redirect is how you make that connection. It tells browsers and crawlers that a page has moved permanently and where it now lives. Google has said that 301 redirects pass ranking signals, so a well-redirected page doesn't lose value simply because it moved.
Most traffic losses after a domain change come from mistakes, not from the move itself:
- Redirecting every old page to the new home page instead of its matching page.
- Missing pages, so old URLs return
404errors. - Using temporary
302redirects or JavaScript redirects. - Changing the site design, URL structure and content at the same time as the domain.
- Letting the old domain expire, which breaks every redirect and backlink at once.
Before You Start: Planning the Move
Change One Thing at a Time
Where possible, move the domain on its own. Keep the same URL paths, content, titles and templates. If you also need a redesign or a new URL structure, do it before or after the domain change, with time in between, so you can tell which change caused any problem.
Check the New Domain's History
If the new domain was previously owned by someone else, check what it was used for. A history of spam, malware or penalties can follow the domain. How to check a domain's history covers archive lookups, blocklists and backlink checks.
Pick a Quiet Time
Avoid your busiest season. Most businesses choose a period when a short dip in organic traffic will do the least damage.
Lower DNS TTLs in Advance
If you'll change DNS records during the move, lower their TTLs a day or two beforehand so changes take effect quickly. See how to lower TTL before a migration.
Prepare the New Domain
- Register it with auto-renew enabled and a registrar lock.
- Point it at your hosting and set up HTTPS. See how to point a domain to a new host.
- Decide whether the canonical version is
wwwor the root domain, and stick with it. - Set up email on the new domain if you'll use it, including SPF, DKIM and DMARC.
Step 1: Build a Complete URL Inventory
You can only redirect pages you know about. Collect every URL from as many sources as possible:
- XML sitemaps on the old domain.
- A full site crawl with a crawler tool.
- Google Search Console: pages with impressions and the indexed pages report.
- Analytics: landing pages with traffic over the past year.
- Backlink tools: URLs on your site that other sites link to, including old pages that no longer exist.
- Server logs: URLs that bots and users actually request.
You can pull URLs from a sitemap on the command line:
curl -s https://old-example.com/sitemap.xml \
| grep -oE '<loc>[^<]+</loc>' \
| sed -E 's#</?loc>##g' > old-urls.txt
wc -l old-urls.txt
412 old-urls.txt
If the site uses a sitemap index, run the same command on each child sitemap it lists. Combine everything, remove duplicates and keep the list as your master inventory.
Step 2: Create the Redirect Map
A redirect map pairs every old URL with its new URL. If you're keeping paths the same, most of the mapping is automatic: old-example.com/anything becomes example.com/anything. Note any exceptions, such as pages you're merging or retiring.
A simple CSV works well:
old_url,new_url
https://old-example.com/,https://example.com/
https://old-example.com/about/,https://example.com/about/
https://old-example.com/blog/first-post/,https://example.com/blog/first-post/
https://old-example.com/services/web-design/,https://example.com/services/design/
https://old-example.com/old-promo/,https://example.com/offers/
Rules for a good map:
- One to one wherever possible: Each old page goes to the most relevant new page.
- No chains: Redirect straight to the final URL, not through intermediate ones.
- Retired pages: Redirect to the closest relevant page. If there's genuinely no equivalent, let it return
404or410rather than redirecting everything to the home page, which search engines may treat as a soft 404. - Include parameters and media: PDFs, images and important query-string URLs need redirects too.
Step 3: Set Up 301 Redirects on the Old Domain
The old domain must keep resolving and serving redirects. Point it at a server or CDN that you control, not a basic registrar forwarding feature that may send everything to the home page. What is domain forwarding explains the difference.
Nginx: Whole-Domain Redirect With Exceptions
When paths stay the same, a single rule handles almost everything. Use a map for the exceptions:
map $request_uri $new_uri {
default $request_uri;
/services/web-design/ /services/design/;
/old-promo/ /offers/;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name old-example.com www.old-example.com;
ssl_certificate /etc/letsencrypt/live/old-example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/old-example.com/privkey.pem;
return 301 https://example.com$new_uri;
}
Note that $request_uri includes the query string, so the exact-match exceptions only apply to requests without parameters. Requests with a query string fall through to the default, which keeps the full path and parameters. Place the map block in the http context, outside any server block.
Apache: .htaccess on the Old Domain
RewriteEngine On
# Exceptions first
RewriteRule ^services/web-design/?$ https://example.com/services/design/ [R=301,L]
RewriteRule ^old-promo/?$ https://example.com/offers/ [R=301,L]
# Everything else keeps its path and query string
RewriteCond %{HTTP_HOST} ^(www\.)?old-example\.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
Apache appends the original query string to the target automatically unless the target contains its own query string.
Cloudflare
If the old domain is on Cloudflare with proxied DNS, create a Redirect Rule:
When incoming requests match: Hostname is in {"old-example.com" "www.old-example.com"}
Then: Dynamic redirect
Expression: concat("https://example.com", http.request.uri.path)
Status code: 301
Preserve query string: on
For exceptions, use Bulk Redirects with a list built from your CSV, and make sure those rules run before the catch-all.
Don't Forget HTTPS on the Old Domain
Visitors and search engines will request https://old-example.com/.... If there's no valid certificate, they see an error instead of a redirect. Keep a certificate for the old domain and its www version for as long as the redirects are live.
Step 4: Update the New Site
On the new domain, remove every trace of the old one:
- Canonical tags:
<link rel="canonical" href="https://example.com/about/">, not the old domain. - Internal links: Search the database and templates for the old domain and replace it.
- XML sitemap: List only new URLs and reference it in
robots.txt. - hreflang, Open Graph and structured data: Update every absolute URL.
- robots.txt: Make sure the new domain isn't blocking crawlers. A staging
Disallow: /that slips into production is a classic mistake. - Hard-coded assets: Images, scripts and fonts loaded from the old domain.
For WordPress, WP-CLI can replace the domain throughout the database safely, including serialised data:
wp search-replace 'https://old-example.com' 'https://example.com' --all-tables --dry-run
wp search-replace 'https://old-example.com' 'https://example.com' --all-tables
Run the --dry-run version first and take a database backup before the real run.
Check robots.txt on both domains. The old domain must not block crawling, because search engines need to fetch old URLs to see the redirects:
curl -s https://example.com/robots.txt
curl -s https://old-example.com/robots.txt
Step 5: Test Every Redirect
Test before and immediately after the switch. A quick check on one URL:
curl -sI https://old-example.com/services/web-design/ | grep -iE '^(HTTP|location)'
HTTP/2 301
location: https://example.com/services/design/
For the whole map, this Python script reads the CSV and reports any URL that doesn't return a single 301 to the expected destination:
import csv
import sys
import urllib.error
import urllib.request
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
opener = urllib.request.build_opener(NoRedirect)
def check(old: str, expected: str) -> tuple[bool, str]:
req = urllib.request.Request(old, method="HEAD", headers={"User-Agent": "redirect-check/1.0"})
try:
resp = opener.open(req, timeout=15)
return False, f"{resp.status} (no redirect)"
except urllib.error.HTTPError as err:
location = err.headers.get("Location", "")
if err.code in (301, 308) and location == expected:
return True, f"{err.code} -> {location}"
return False, f"{err.code} -> {location or 'no Location header'}"
except urllib.error.URLError as err:
return False, f"error: {err.reason}"
failures = 0
with open(sys.argv[1], newline="") as f:
for row in csv.DictReader(f):
ok, detail = check(row["old_url"], row["new_url"])
if not ok:
failures += 1
print(("OK " if ok else "FAIL ") + row["old_url"] + " " + detail)
print(f"\n{failures} problem(s) found")
sys.exit(1 if failures else 0)
python3 check_redirects.py redirect-map.csv
OK https://old-example.com/ 301 -> https://example.com/
OK https://old-example.com/about/ 301 -> https://example.com/about/
OK https://old-example.com/blog/first-post/ 301 -> https://example.com/blog/first-post/
FAIL https://old-example.com/old-promo/ 302 -> https://example.com/offers/
OK https://old-example.com/services/web-design/ 301 -> https://example.com/services/design/
1 problem(s) found
Then check the destinations themselves return 200. A redirect to a broken page is no better than a 404.
Step 6: Tell Search Engines About the Move
Google Search Console
- Verify both domains, ideally as Domain properties using a DNS TXT record. See how to verify domain ownership with a TXT record.
- Submit the new sitemap in the new property.
- Open the old property, go to Settings, then Change of address, and select the new property. Google runs checks, including whether the home page redirects correctly, before accepting it.
The Change of Address tool works at domain level, so it's for moves from one domain to another, not for moving to a subfolder. Google says the request stays active for 180 days, so keep the redirects in place well beyond that.
Bing Webmaster Tools
Bing has its own Site Move tool. Verify both sites and submit the move there as well.
Leave the Old Sitemap Accessible for a While
Some SEOs keep a sitemap of old URLs submitted in the old property for a few weeks so search engines recrawl them sooner and discover the redirects. Remove it once most old URLs have dropped out of the index.
Step 7: Update Everything That Points to the Old Domain
Redirects preserve value, but direct links are better:
- Your most valuable backlinks: Ask the sites behind them to update the URL.
- Business listings and profiles: Google Business Profile, social media, directories and review sites.
- Paid ads: Update final URLs in ad accounts to avoid unnecessary redirects and disapprovals.
- Email signatures, documents and printed material.
- Third-party tools: Analytics, tag managers, payment providers, CRM forms and any API callbacks or OAuth redirect URIs.
- Email: If addresses move to the new domain, keep the old domain's MX records and forward mail for as long as people use the old addresses.
Step 8: Monitor the Results
Watch closely for the first few weeks:
- Search Console Page indexing report on both properties: new URLs should rise as old ones fall.
- Crawl errors and 404s on the old domain, which reveal URLs missing from your map.
- Organic traffic and rankings for your key pages, compared with the same period before the move.
- Server logs for requests to old URLs that aren't redirected properly.
A temporary drop and some ranking fluctuation are normal while search engines recrawl. Losses that persist after a couple of months usually point to missing redirects, blocked crawling or content changes made at the same time.
Step 9: Keep the Old Domain Forever, If You Can
Google recommends keeping redirects in place for at least a year, but the safest approach is to keep the old domain registered and redirecting indefinitely. Backlinks, bookmarks and printed material will keep sending people to it for years.
If you let it expire, two bad things happen: every redirect stops working, and someone else can register the domain and take advantage of your old backlinks or impersonate you. Turn on auto-renew, lock it at the registrar and treat it like any other important domain. See what happens when a domain expires for the risks.
Common Mistakes to Avoid
- Redirecting everything to the home page: Loses page-level relevance and may be treated as soft 404s.
- Using 302 redirects: Signals a temporary move, so search engines may keep the old URLs.
- Redirect chains:
http://oldtohttps://oldtohttps://www.newtohttps://newwastes crawl budget and adds latency. Go straight to the final URL. - Blocking the old domain in robots.txt: Crawlers can't see the redirects.
- Leaving canonical tags pointing at the old domain: Sends contradictory signals.
- Forgetting subdomains:
blog.old-example.comorshop.old-example.comneed their own redirects. - Dropping the old domain too soon.
FAQ: Changing Domains Without Losing SEO
Most sites see a temporary dip while search engines process the move. With complete page-to-page 301 redirects and no other major changes, rankings usually recover within weeks to a few months.
At least a year, as Google recommends, but ideally permanently. Keeping the old domain renewed and redirecting protects backlinks and stops someone else from registering it.
Yes. Google treats permanent redirects as a strong signal to move ranking signals from the old URL to the new one. The redirect must point to a relevant page to be effective.
It isn't required, but it helps Google understand the move faster. It only works when the old site has working 301 redirects and both domains are verified in Search Console.
You can, but it makes problems harder to diagnose and increases the risk of losses. If possible, change the domain first with the same content and URLs, then redesign later.
Usually not. Basic registrar forwarding often sends every request to the home page or can't handle path exceptions and HTTPS properly. Use redirects on a server or CDN you control.
They stop working only if you remove the old domain's MX records. Keep mail flowing to the old addresses, or forward it, until customers and contacts have switched to the new ones.
Conclusion
Moving to a new domain without losing SEO comes down to one principle: make it easy for search engines to connect every old page to its new home. Build a complete URL inventory, map each old URL to its exact equivalent, implement permanent 301 redirects on the old domain over HTTPS, and update canonicals, internal links and sitemaps on the new one. Then verify both domains in Search Console and submit the Change of Address request.
After the switch, test every redirect with a script, watch indexing and 404 reports closely, and fix gaps quickly. Most importantly, keep the old domain registered and redirecting for the long term. A domain move done this way usually costs no more than a short, temporary dip, and your rankings, backlinks and visitors follow you to the new address.


