www and non-www both resolve: one site answering at two addresses

https://example.com and https://www.example.com are different origins. If both serve your pages with a 200 status, each page has two URLs, links get split between them, and Google chooses which to show. Pick one host, then make every other protocol and host combination redirect to it with a single 301.

Canonical tags soften the problem, since both copies can point at one address, but a redirect removes it. It also stops visitors and other sites from linking to the version you did not choose.

Test all four origins

code
for o in http://example.com http://www.example.com https://example.com https://www.example.com; do
  curl -s -o /dev/null -w "$o -> %{http_code} %{redirect_url}\n" "$o/sample-post/"
done

Use a deep URL, not only the homepage, because some configurations redirect the root and nothing else. The healthy result is one line showing 200 and three showing 301 with a redirect_url that is already the final address, including the path. Two results need attention:

  • More than one 200. The duplicate-host problem this page describes.
  • A redirect that lands on another redirect, for example http://www to https://www to https://example.com. It works, but it is a chain. Aim for one hop.

Also check that the losing host has a valid TLS certificate. If https://www.example.com shows a certificate warning, browsers stop before any redirect can happen.

Why WordPress does not always handle it

WordPress normally redirects requests on the wrong host to the Site Address through its canonical redirect. So when both hosts answer 200, something is getting in before WordPress or changing what it sees:

  • A page cache or CDN serving cached HTML for whichever host was requested, without running WordPress.
  • Static files. Images, PDFs and other uploads are served by the web server directly on both hosts.
  • A plugin or snippet that disables canonical redirects, sometimes added to solve an unrelated redirect loop.
  • Site address filters, used by some multi-domain setups, that make WordPress accept any host it is called on.
  • A reverse proxy rewriting the Host header, so WordPress believes every request is for the configured host.

Add the redirect at the server

Do it in the web server or CDN, so it applies to every file and runs before caching.

nginx, redirecting everything to the bare HTTPS domain:

code
server {
  listen 80;
  listen 443 ssl;
  server_name www.example.com;
  return 301 https://example.com$request_uri;
}
server {
  listen 80;
  server_name example.com;
  return 301 https://example.com$request_uri;
}

Apache, in .htaccess above the WordPress block:

code
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]

Behind a proxy or CDN that terminates TLS, %{HTTPS} may always read "off" at the origin. Test X-Forwarded-Proto instead, or create the rule in the CDN, otherwise you will produce a redirect loop. To prefer www, swap the hostnames. Neither choice is better for search; consistency is the point.

Align everything else with the chosen host

  1. Settings → General: WordPress Address and Site Address use the chosen origin.
  2. Canonical tags: view source and confirm the canonical uses it. Hydrogen SEO builds canonicals from the site address, so step one covers this.
  3. Internal links and the sitemap: no references to the other host. See internal links to redirected URLs for cleaning up old links in content.
  4. Search Console: a Domain property covers all four origins in one place. If you use URL-prefix properties, the data for the retired host will fall away as Google consolidates.
  5. External profiles you control, such as social accounts and business listings, should link to the chosen form.

What happens in Google

You do not need to request anything. As Googlebot recrawls the duplicate host it meets the 301s and consolidates onto the target. In the Page indexing report the retired host's URLs appear under "Page with redirect", which is the correct final state. If you previously saw "Duplicate, Google chose different canonical than user" with the other host as Google's choice, that should resolve as the redirects are picked up.

Retest the four origins

Run the loop again and confirm one 200 and three single-hop 301s, for a post URL and for a static file such as an image in /wp-content/uploads/. Check from a private window that typing the other host lands on the chosen one with the full path preserved. The free SEO audit checks that the URL you test is served over HTTPS and has a canonical tag; run it on the chosen origin to confirm both.

Common questions

Is www or non-www better for SEO?

Neither. Google treats them equally. Choose one and use it everywhere.

Is a canonical tag enough without a redirect?

It usually gets Google to index one version, but people can still land on and link to the other, and canonicals are hints. A 301 is definitive.

Do I need to set a preferred domain in Search Console?

No. That setting was removed years ago. Google works out the preferred host from redirects, canonicals and links.

Will adding the redirect cause a ranking drop?

Consolidating two hosts that already serve the same content is low risk. Expect a short period where reports show both while Google recrawls.