Pick www.example.com or example.com, serve the site on that one host, and permanently redirect the other with the path and query intact. Either choice works; the setups that cause trouble serve both hosts, or redirect between them inconsistently. What should decide it is how your DNS provider handles the apex, what your hosting platform recommends, how you scope cookies, and how far you plan to take HSTS.

What 12 sites actually do

On 26 September 2026 we requested http:// and https:// on both the apex and www of 12 sites, 11 well-known ones plus our own, from a workstation in South Korea. The run started at 14:42 UTC and was repeated at 14:43 UTC. Each hop was a separate curl -sI (a HEAD request, without -L), so every status code and Location header was recorded. The two runs matched, apart from one transient HTTP/2 error on www.microsoft.com that returned 200 on retry. Preload status comes from the hstspreload.org status API, queried at 14:44 UTC.

Site Canonical host Status codes seen From http:// on the other host HSTS on the canonical page Preload API status
github.com apex 301 2 hops, via https://www max-age=31536000; includeSubdomains; preload preloaded
google.com www 301 never reaches HTTPS none unknown
cloudflare.com www 301 1 hop max-age=31536000; includeSubDomains preloaded
vercel.com apex 308 2 hops, via https://www max-age=31536000; includeSubDomains; preload preloaded
netlify.com www 301 2 hops, via the https:// apex max-age=31536000; includeSubDomains; preload preloaded
stripe.com apex 301 2 hops, via https://www max-age=63072000; includeSubDomains; preload preloaded
wikipedia.org www 301 2 hops, via the https:// apex max-age=106384710; includeSubDomains; preload preloaded
apple.com www 301 1 hop max-age=31536000; includeSubdomains; preload unknown
microsoft.com www 307, 301 2 hops, via the https:// apex none unknown
mozilla.org www 302, 301 2 hops, via the https:// apex max-age=31536000 unknown
python.org www 301 1 hop max-age=63072000; includeSubDomains; preload preloaded
and.guide apex 301 1 hop none unknown

“From http:// on the other host” counts the redirects from the plain-HTTP URL of the non-canonical host to the canonical HTTPS URL. The API returned preloaded for seven domains and unknown for the other five, none of which it lists as preloaded.

Live capture, 26 September 2026. Two ways to get from plain HTTP on the apex to https://www:

$ curl -sI http://netlify.com/
HTTP/1.1 301 Moved Permanently
Location: https://netlify.com/
Server: Netlify

$ curl -sI https://netlify.com/
HTTP/2 301 
location: https://www.netlify.com/
server: Netlify
strict-transport-security: max-age=31536000; includeSubDomains; preload

$ curl -sI http://cloudflare.com/
HTTP/1.1 301 Moved Permanently
Location: https://www.cloudflare.com/
Server: cloudflare

Netlify upgrades the scheme on the apex first and attaches its HSTS policy to the apex’s HTTPS redirect. Cloudflare sends plain-HTTP visitors straight to the final URL in one step.

Live capture, 26 September 2026. The status codes other than 301 that we saw:

$ curl -sI http://www.vercel.com/
HTTP/1.0 308 Permanent Redirect
Location: https://www.vercel.com/
server: Vercel

$ curl -sI https://www.vercel.com/
HTTP/2 308 
location: https://vercel.com/
server: Vercel
strict-transport-security: max-age=63072000; includeSubDomains; preload

$ curl -sI http://mozilla.org/
HTTP/1.1 302 Found
Location: https://mozilla.org:443/

What the table supports, and what it does not:

  • Both choices are common. Eight sites use www and four use the apex. The list is hand-picked, not a sample, so read it as an illustration rather than a statistic. Vercel’s documentation recommends www, yet vercel.com itself runs on the apex; the recommendation is about how Vercel’s network steers traffic, not a rule.
  • Host changes were always permanent. Every apex-to-www or www-to-apex redirect was a 301, or a 308 at Vercel. Temporary codes appeared only on scheme upgrades: 302 at mozilla.org and 307 at microsoft.com.
  • Hop counts vary. Seven sites need two hops from a plain-HTTP non-canonical URL and four need one. google.com never reached HTTPS for our client: http://google.com/ redirected to http://www.google.com/, which answered 200 over plain HTTP, as did http://www.microsoft.com/. Our requests carried no HSTS state and no preload list, so these rows show what a first-time client that does not upgrade on its own sees.
  • HSTS is common but uneven. Nine of the 12 sent HSTS on the canonical page and seven are preloaded. mozilla.org’s canonical policy has no includeSubDomains.

The DNS constraint at the apex

RFC 1034 says a name that owns a CNAME record should own no other data. The apex always owns SOA and NS records, so a standard CNAME cannot live there. Many DNS providers offer a workaround, such as CNAME flattening or an ALIAS-style record that resolves the target and answers with addresses; our guide to CNAME flattening explains how they differ. Without one, the apex needs A and AAAA records that point at your platform’s addresses, while www can use a CNAME.

That constraint shapes what platforms recommend:

Platform What its documentation recommends
Vercel Make www the primary domain and redirect the apex to it, so a CNAME lets Vercel’s CDN steer traffic; the reverse works too but gives Vercel less control
Netlify With external DNS, make www the primary domain, because apex resolution through third-party DNS can hurt performance; with Netlify DNS, both perform equally
GitHub Pages If you use the apex, also set up www; the apex takes four A and four AAAA records and www a CNAME to your github.io host

Cloudflare Pages handles apex and subdomain custom domains differently; our Cloudflare Pages custom domain guide covers both paths. If your DNS host cannot flatten the apex and your platform wants a CNAME, www is the path of least resistance.

Cookies follow the Domain attribute, not the hostname

Cookie isolation is a classic argument for www. Under RFC 6265, the Domain attribute decides where a cookie goes:

  • A cookie set without Domain is returned only to the host that set it, so an apex site’s host-only cookies never reach static.example.com.
  • A cookie with Domain=example.com is sent to example.com and to every name under it, however deep, no matter which host is canonical.

The canonical host does not decide cookie scope; the attribute does. The old argument does have a basis: RFC 6265 itself warned that some user agents of its day treated a missing Domain as the current host name and sent apex cookies to www as well. If such clients still matter to you, a www host sidesteps the problem.

In practice, audit every Set-Cookie header for Domain=. Anything scoped to the registrable domain reaches every subdomain, including any you point at third-party services.

HSTS: includeSubDomains ties the two hosts together

RFC 6797 defines includeSubDomains as extending a host’s policy to that host’s subdomains, which only works downward. A policy that a browser receives from www.example.com covers www.example.com and names beneath it. It never covers example.com, api.example.com, or any other sibling. Once a browser holds a policy, it rewrites http:// URLs for the covered hosts to https:// before loading them, including when following redirects, so returning visitors to those hosts skip the plain-HTTP request entirely.

To protect the whole domain through headers, the apex must send the policy with includeSubDomains over HTTPS, and browsers must load an HTTPS URL on the apex at least once. On an apex-canonical site that happens with every page view. On a www-canonical site the apex is only ever a redirect, so the redirect itself has to carry the policy.

The preload list’s submission requirements encode exactly this. Redirect HTTP to HTTPS on the same host; serve the HSTS header on the base domain with a max-age of at least 31,536,000 seconds, includeSubDomains, and preload; and if the HTTPS site redirects elsewhere, that redirect must carry the header. For a www site, first-time plain-HTTP visitors therefore take two hops: http://example.com/ to https://example.com/ to https://www.example.com/. hstspreload.org also warns that a removal from the list takes months to reach users.

Here is what the apex told browsers on the eight www-canonical sites in our survey:

Site http:// apex goes first to HSTS on the https:// apex redirect
netlify.com 301 to https://netlify.com/ max-age=31536000; includeSubDomains; preload
wikipedia.org 301 to https://wikipedia.org/ max-age=106384710; includeSubDomains; preload
microsoft.com 307 to https://microsoft.com/ max-age=31536000
mozilla.org 302 to https://mozilla.org:443/ max-age=60; includeSubDomains
cloudflare.com 301 to https://www.cloudflare.com/ max-age=15780000; includeSubDomains
python.org 301 to https://www.python.org/ max-age=315360000; preload
apple.com 301 to https://www.apple.com/ none
google.com 301 to http://www.google.com/ none

Only netlify.com and wikipedia.org follow the full pattern. microsoft.com and mozilla.org upgrade on the apex first, but their apex policies either omit includeSubDomains or last 60 seconds. cloudflare.com and python.org are preloaded, yet they send plain-HTTP apex visitors straight to https://www, so being on the list is not proof that a domain meets today’s submission checks. Several sites (stripe.com, www.apple.com, and python.org) also attach HSTS headers to plain-HTTP responses; RFC 6797 tells browsers to ignore the header there, so it does nothing.

If you do not plan to preload, sending plain-HTTP visitors straight to the canonical HTTPS URL in one hop is simpler and faster. Our teardown of and.guide measured what an extra connection to a redirect host costs. For staging includeSubDomains and preload safely, see HSTS preload and subdomains.

Search engines: one host, permanent redirects, matching signals

Google treats redirects and rel="canonical" as strong canonicalization signals and sitemap inclusion as a weak one, and it prefers HTTPS over HTTP unless other signals conflict. Its redirect documentation says 301 and 308 tell the indexing pipeline that the target should be canonical, while 302, 303, and 307 do not. Google also advises against choosing a canonical with robots.txt or noindex, and against pointing different methods at different URLs.

For a host choice, that means:

  1. A permanent redirect (301 or 308) from every non-canonical variant, keeping the path and query.
  2. An absolute rel="canonical" URL on the canonical host in every page.
  3. Sitemaps that list only canonical-host URLs.
  4. Internal links on the canonical host, so crawlers and readers rarely hit a redirect.

Choosing between 301 and 308 comes down to request methods. RFC 9110 still allows a client to change a POST into a GET when it follows a 301 or 302, and points to 308 and 307 when that is undesirable. For page navigation the two behave alike; if forms or API clients might post to the non-canonical host, a 308 keeps the method and body.

Setting it up on four platforms

Cloudflare

For a zone on Cloudflare, the documented “Redirect from WWW to root” example is a Single Redirect with a wildcard pattern:

Request URL:            https://www.*
Target URL:             https://${1}
Status code:            301
Preserve query string:  enabled

As documented, the pattern matches only HTTPS requests, so decide separately how http://www requests are upgraded.

Cloudflare’s Pages documentation uses an account-level Bulk Redirect instead, plus a proxied placeholder record so that www traffic reaches Cloudflare at all:

Source URL:   www.example.com
Target URL:   https://example.com
Status code:  301
Parameters:   preserve query string, subpath matching, preserve path suffix, include subdomains
DNS record:   A  www  192.0.2.1  (Proxied)

A Bulk Redirect source without a scheme matches both http and https, so one rule takes plain-HTTP www visitors to the HTTPS apex in a single hop.

Vercel

Add both hosts to the project; adding an apex domain prompts you to add its www counterpart. Open Domains in the project settings, select Edit on the host you are leaving, and pick the canonical host in the Redirect to dropdown. Vercel says it attempts the www/non-www redirect automatically, but notes you may still want to add it explicitly. In our survey, vercel.com’s own redirects were 308s.

Netlify

Assign the host you want as the primary domain. Assigning either the apex or www as primary adds both to the Production domains panel, and Netlify automatically redirects the other one to the primary. To switch later, choose Options and then Set as primary domain next to the domain. The documentation does not state the status code; netlify.com’s own redirects in our survey were 301s.

GitHub Pages

Set the canonical host as the site’s custom domain, then publish DNS for both names:

example.com.      3600  IN  A      185.199.108.153
example.com.      3600  IN  A      185.199.109.153
example.com.      3600  IN  A      185.199.110.153
example.com.      3600  IN  A      185.199.111.153
example.com.      3600  IN  AAAA   2606:50c0:8000::153
example.com.      3600  IN  AAAA   2606:50c0:8001::153
example.com.      3600  IN  AAAA   2606:50c0:8002::153
example.com.      3600  IN  AAAA   2606:50c0:8003::153
www.example.com.  3600  IN  CNAME  your-user.github.io.

With records for both names in place, GitHub redirects the other name to the custom domain automatically: set www.example.com as the custom domain and the apex redirects to it, or the reverse. GitHub also warns against wildcard records such as *.example.com because they put you at risk of domain takeover. Our GitHub Pages custom domain guide covers verification and HTTPS.

A short decision table

If this describes you Lean Why
Your DNS host cannot flatten or alias the apex, and your platform wants a CNAME www A standard CNAME cannot sit at the apex
You host on Vercel, or on Netlify with external DNS www Both platforms’ documentation recommends it
Your DNS supports flattening or ALIAS and you want the shortest URL apex The bare domain people type is the final host, with no host redirect
You need cookies shared across subdomains either The Domain attribute decides scope, not the host
You plan to preload HSTS either The apex must serve HTTPS with includeSubDomains; a www site needs the two-hop upgrade
One host already has years of links and rankings keep it Switching means redirecting every URL again

Check your own setup

for u in http://example.com/ https://example.com/ http://www.example.com/ https://www.example.com/; do
  echo "== $u"
  curl -sI "$u" | grep -iE '^(HTTP/|location:|strict-transport-security:)'
done
curl -sI 'http://www.example.com/pricing?plan=pro' | grep -i '^location:'
curl -s https://example.com/pricing | grep -oE '<link[^>]*rel="canonical"[^>]*>'

Follow each Location by hand, as we did for the survey, and confirm that:

  1. every non-canonical URL ends on the canonical HTTPS URL, with a 301 or 308 wherever the host changes;
  2. the path and query string survive every hop;
  3. the canonical host’s HTTPS responses carry your HSTS header, and for a www site you plan to preload, so does the https:// apex redirect, reached from http:// on the apex first;
  4. the rel="canonical" URL uses the same host your redirects end on.