www and non-www Both Open Separately

Both yourdomain.com and www.yourdomain.com load with a 200 and identical content. Why it splits SEO signals and the exact 301 fix per host.

You type https://yourdomain.com and the site loads. You type https://www.yourdomain.com and the same site loads, identical content. Both return 200. It looks fine, but to Google’s deduplication and to anything counting your backlinks, you have two sites with identical content competing against each other.

Fastest fix: pick one hostname as canonical, then make the other return a 301 redirect to it at the host/CDN level (not just an HTML <link rel="canonical"> tag). A canonical tag tells crawlers your preference; a 301 actually moves real visitors and backlink credit onto one URL. Confirm the fix with one command:

curl -sI https://www.yourdomain.com | grep -i -E "http|location"

You want to see 301 and a Location: header pointing at your canonical host. If you see 200, the redirect is not in place yet.

This is the harder cousin of www vs root redirect: there, one version never resolves; here, both already work, so you also have to clean up indexing and backlinks after wiring the redirect.

Why this actually matters (it is not cosmetic)

yourdomain.com and www.yourdomain.com are different hostnames, so search engines treat them as different URLs unless you tell them otherwise. Without a 301:

  • Backlinks split between the two hosts, so neither accumulates full authority.
  • Google picks its own canonical (it may not be the one you want — see Google’s canonicalization troubleshooting guide), and reporting in Search Console gets murky.
  • Analytics, cookies, and any same-site auth can behave inconsistently across the two hosts.

Which bucket are you in?

Run the two curl checks below, then match the result to the cause.

What you observeMost likely causeWhere to fix
Both hosts return 200 directly from your hostBoth added as separate domains, no redirect setHost dashboard (Vercel / Netlify / Firebase)
Both 200, server is behind Cloudflare (proxied)Both DNS records proxied, no redirect ruleCloudflare Redirect Rules
Both 200, HTML has a canonical tagCanonical tag set but no HTTP 301Add the 301 at host/CDN level
Both 200, self-hostedOne nginx/Apache server_name serves bothAdd a redirect server block
One returns 301, the other 200Redirect already correct — finish indexing cleanupSearch Console + internal links

Diagnostic commands:

curl -sI https://yourdomain.com | head -5
curl -sI https://www.yourdomain.com | head -5

HTTP/2 200 on both means no redirect. HTTP/2 301 with a Location: header on one means that side is already redirecting.

Common causes

Ordered by hit rate, highest first.

1. Both versions added to the host without a redirect

You added both yourdomain.com and www.yourdomain.com as separate domains on Vercel/Netlify. The host serves both happily and does not set up a redirect by default.

How to spot it: Host dashboard → Domains → both look like equal “primary” entries. You want exactly one primary and one redirect.

2. CDN proxies both directly to origin

If Cloudflare (or another CDN) has both records as proxied A/AAAA/CNAME, both reach origin and serve content. The CDN does not redirect unless you add a rule.

How to spot it: both curl -sI checks above return 200. In the Cloudflare DNS tab both records show the orange “Proxied” cloud.

3. Host supports both bindings but will not infer a primary

Some hosts let you add both names but require you to manually pick the primary. They do not assume which one you want.

How to spot it: the host docs say “add both, then set one as primary” — and you stopped after adding both.

4. Canonical tag set but no HTTP redirect

You added <link rel="canonical" href="https://yourdomain.com/..."> on every page. The tag is a hint for Google, but visitors still see the host they typed, and raw backlinks still point at the non-canonical host.

How to spot it: both URLs return 200 (not 301). A canonical tag never redirects.

5. Self-hosted nginx/Apache serving both names

Older shared hosting or a hand-written config may have one server_name yourdomain.com www.yourdomain.com; block with no redirect rule. Both names work, and you have a duplicate-content problem.

How to spot it: SSH in and read the config. If server_name lists both names in one block with no separate redirect server block, that is the cause.

Shortest path to fix

Step 1: Pick the canonical host

Either choice is SEO-neutral — Google has confirmed there is no ranking difference. Pick on technical grounds:

  • Apex (yourdomain.com) for shorter URLs, if your DNS provider supports ALIAS/ANAME/flattened-CNAME at the apex. The DNS spec forbids a plain CNAME on an apex record, which is why some hosts steer you toward www.
  • www (www.yourdomain.com) for the simplest CDN setup, because www is a normal subdomain and takes a plain CNAME. As of June 2026, Vercel explicitly recommends www as primary for exactly this reason (more CDN control over incoming traffic).

Decide once, write it down, and keep every internal link, sitemap entry, and canonical tag consistent with it.

Step 2: Configure the redirect at the host/CDN

Vercel — Project → Settings → Domains:

  • Add both yourdomain.com and www.yourdomain.com (adding the apex auto-suggests its www counterpart).
  • Click Edit on the non-canonical domain, open the Redirect to dropdown, and select the canonical host.
  • Vercel issues a 308/301-class permanent redirect automatically. (Vercel uses 308 by default, which preserves the method and is treated as permanent by search engines just like 301.)

Netlify — Site configuration → Domain management → Domains:

  • Add both names.
  • Set the canonical one as primary domain; the other becomes a domain alias.
  • Netlify auto-redirects the alias to the primary. This automatic behavior covers apex ↔ www only; other subdomains need manual redirect rules.

Firebase Hosting — when you add the second domain in the console, choose the “Redirect to an existing site/domain” option and point it at the canonical. For config-as-code, set a catch-all redirect in firebase.json on the non-canonical site and deploy with firebase deploy --only hosting:

{
  "hosting": {
    "redirects": [
      { "source": "**", "destination": "https://yourdomain.com", "type": 301 }
    ]
  }
}

Cloudflare — Page Rules are legacy; use Redirect Rules. Dashboard path: Rules → Templates → “Redirect from WWW to Root” (or “Redirect from Root to WWW”) → Create a Rule. To build it by hand, go to Rules → Redirect Rules → Create rule and use a wildcard:

When incoming requests match:  https://www.yourdomain.com/*
Then redirect to URL (dynamic): https://yourdomain.com/${1}
Status code:                    301
Preserve query string:         On

Note the modern token is ${1} (the older Page Rules used $1). Deploy the rule, and keep the matching DNS record proxied (orange cloud) so the rule actually runs.

Self-hosted nginx — split the redirect into its own server block:

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

Then reload with nginx -t && systemctl reload nginx. Apache equivalent: a Redirect 301 / mod_rewrite rule scoped to the www VirtualHost.

Step 3: Verify the redirect

curl -sI https://www.yourdomain.com | head -5

You want:

HTTP/2 301
location: https://yourdomain.com/

308 from Vercel is also correct. A 200 means the redirect is not live yet. Also test a deep path so the redirect preserves it, not just the homepage:

curl -sI https://www.yourdomain.com/some-article/ | grep -i location
# expect: location: https://yourdomain.com/some-article/

Step 4: Make the HTML canonical tag agree

Your template’s canonical must point at the canonical host on every page:

<link rel="canonical" href="https://yourdomain.com/your-article/" />

Never the alternative host. A redirect plus a contradicting canonical tag sends mixed signals.

Step 5: Fix Search Console (the modern way)

If you verified the two hosts as separate URL-prefix properties, the cleanest fix is to add a single Domain property for yourdomain.com. A Domain property automatically consolidates http/https, www, and non-www, and all subdomains into one unified report, so you stop stitching numbers across two properties. Verify it once via the DNS TXT record Google gives you.

Keep the old URL-prefix properties if you like (handy for watching the non-canonical host drain), but treat the canonical host as primary.

Step 6: Confirm Google picked the right canonical

Open Search Console → URL Inspection, paste a non-canonical URL (e.g. https://www.yourdomain.com/your-article/), and check “User-declared canonical” vs “Google-selected canonical”. After the 301 is crawled, Google-selected should converge on your canonical host. Google explicitly notes it may pick a different canonical than you declared, so this check is the real proof — not the redirect alone.

Consolidation is gradual: over roughly 2–4 weeks Google re-crawls and moves link equity onto the canonical. In Search Console → Indexing → Pages, the non-canonical URLs should drift into the “Alternate page with proper canonical tag” / “Page with redirect” buckets.

How to confirm it is fully fixed

  1. curl -sI on the non-canonical host returns 301/308 with the right Location: (root and a deep path).
  2. The canonical host returns 200 directly (it must not redirect to itself — that would loop).
  3. URL Inspection shows Google-selected canonical = your chosen host.
  4. Over 2–4 weeks, indexed non-canonical URLs trend toward zero.

When it is not on you

A few host quirks are real: Firebase’s per-site model, Cloudflare’s apex-vs-subdomain proxy handling, and DNS providers that lack ALIAS/ANAME at the apex. If the host’s behavior contradicts its own docs, open a support ticket with your exact curl -sI output attached.

Easy to misdiagnose as

Setting the <link rel="canonical"> tag alone does not stop dual serving — both hosts still answer 200. Only the 301/308 at the host/CDN level consolidates real traffic and backlinks. If you “added a canonical tag” and both URLs still load, you have not finished the fix.

Prevention

  • Decide www vs apex on day one of any new domain.
  • Always set the redirect at the host/CDN level, not just in a canonical tag.
  • After any DNS or hosting change, re-verify with curl -sI that one host 301s to the other.
  • Use a single Search Console Domain property from the start so consolidation is automatic.
  • For team-managed domains, record the canonical choice in a DOMAIN.md file.

FAQ

  • Is www or apex better for SEO? No ranking difference; Google has said so directly. Pick on technical grounds (apex needs ALIAS/ANAME; www takes a plain CNAME).
  • My host returns 308, not 301 — is that wrong? No. 308 is a permanent redirect that also preserves the HTTP method. Vercel uses it by default and search engines treat it like 301 for consolidation.
  • Do I still need the canonical tag if the 301 is live? Yes. The 301 handles visitors and crawlers that hit the wrong host; the canonical tag reinforces your choice and covers edge cases like parameterized URLs.
  • How long until Google consolidates? Usually 2–4 weeks of re-crawling. Watch the Google-selected canonical in URL Inspection rather than guessing.
  • Can I switch the canonical later? Yes, but it means a redirect chain (old canonical → new canonical), canonical-tag updates, and 4–8 weeks for Google to fully shift. Do not switch casually.
  • Both already redirect to each other and the site is down — why? You created a redirect loop (each host points at the other). The canonical host must return 200; only the non-canonical host should 301.

Tags: #Domain #DNS #SSL #Troubleshooting #Redirect