Com www ou sem www: escolha um endereço e redirecione o outro em um salto
Defina o host canônico do site, configure DNS e certificado para os dois nomes, redirecione o outro com 301 direto para o HTTPS final e confira as quatro combinações com curl.
O site da Oficina do Código respondia igual em oficinadocodigo.com.br e em www.oficinadocodigo.com.br. Metade dos links externos apontava para cada um, o Search Console mostrava as mesmas páginas em dois endereços e os clientes reclamavam de ter de fazer login de novo ao trocar de um para o outro. A resposta curta: escolha um dos dois como endereço oficial e faça o outro responder com um redirecionamento 301 direto para a mesma página no HTTPS do escolhido, em um único salto. Certificado cobrindo os dois nomes, canonical e sitemap usando só o escolhido. Tanto faz qual você escolhe; o que importa é escolher.
Este guia mostra como fazer a escolha, configurar DNS, certificado e nginx, e testar as quatro combinações de endereço com um comando.
Por que dois endereços viram dois sites pela metade
Para o navegador e para a busca, exemplo.com.br e www.exemplo.com.br são hosts diferentes. Se os dois respondem com 200 e o mesmo conteúdo, a busca vê páginas duplicadas e precisa adivinhar qual mostrar. Os links que outros sites fazem para você se dividem entre as duas versões, e as métricas de cada página também.
Cookies agravam o problema. Um cookie criado em www.exemplo.com.br sem o atributo Domain só volta para esse host exato. Quem fez login no www e cai no endereço sem www aparece deslogado. Carrinho, preferências e sessão somem na troca.
A solução não é fazer os dois funcionarem perfeitamente, e sim fazer só um funcionar e o outro apontar para ele. Assim existe uma casa só, e todo link, cookie e métrica termina nela.
Como escolher entre www e o domínio sem prefixo
Do ponto de vista da busca, não há vantagem de um sobre o outro. A escolha é prática:
- Se o site já existe, fique com o endereço que tem mais links e mais tráfego. Olhe no Search Console e nos seus próprios links antigos. Trocar sem motivo é criar trabalho e risco.
- Domínio sem prefixo (o "apex") é mais curto e é o que as pessoas digitam. Só que o apex não pode ser um CNAME no DNS, o que complica quando o site fica atrás de um serviço que entrega um nome em vez de um IP. Alguns provedores de DNS resolvem isso com registros do tipo ALIAS, ANAME ou "CNAME flattening".
- Com www, o host pode ser um CNAME sem truque nenhum, e cookies do site principal ficam separados de outros subdomínios.
A Oficina do Código escolheu o domínio sem www, porque era o que aparecia na maioria dos links e no cartão de visita.
Como configurar passo a passo
- DNS para os dois nomes. O apex com registros A (e AAAA, se você tem IPv6) apontando para o servidor. O www como CNAME para o apex, ou com os mesmos A e AAAA. Os dois precisam resolver, senão quem digitar o outro nome nem chega ao redirecionamento.
- Certificado com os dois nomes. O redirecionamento de
https://www...só acontece depois do TLS. Se o certificado não cobre o www, o navegador mostra erro antes de ver o 301. - Redirecionamento direto para o destino final. HTTP do apex, HTTP do www e HTTPS do www vão, cada um, em um salto, para o HTTPS do apex, preservando caminho e parâmetros.
- Canonical, sitemap e links internos com o host escolhido. Nada no seu próprio site deve apontar para a versão que redireciona.
- Propriedade de domínio no Search Console. Ela cobre todos os hosts e protocolos, o que facilita ver se ainda há tráfego chegando pela versão antiga.
- Teste as quatro combinações. Com
curl, não só no navegador, que guarda cache de redirecionamento.
Certificado para os dois nomes
Com Let's Encrypt e o plugin do nginx, um único certificado cobre os dois nomes:
sudo certbot --nginx -d oficinadocodigo.com.br -d www.oficinadocodigo.com.br
A configuração do nginx
Três blocos server: um para todo o HTTP, um para o HTTPS do www e o principal. Repare que o bloco da porta 80 manda direto para o HTTPS do apex, sem passar por https://www no meio:
# HTTP dos dois nomes: um salto até o destino final
server {
listen 80;
listen [::]:80;
server_name oficinadocodigo.com.br www.oficinadocodigo.com.br;
return 301 https://oficinadocodigo.com.br$request_uri;
}
# HTTPS do www: mesmo certificado, só redireciona
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.oficinadocodigo.com.br;
ssl_certificate /etc/letsencrypt/live/oficinadocodigo.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/oficinadocodigo.com.br/privkey.pem;
return 301 https://oficinadocodigo.com.br$request_uri;
}
# o site de verdade
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name oficinadocodigo.com.br;
ssl_certificate /etc/letsencrypt/live/oficinadocodigo.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/oficinadocodigo.com.br/privkey.pem;
root /var/www/oficinadocodigo;
# ...
}
O $request_uri leva o caminho e a query string originais, então www.oficinadocodigo.com.br/precos?plano=anual chega em oficinadocodigo.com.br/precos?plano=anual, não na home. Se o seu servidor tem outros sites, vale entender como o nginx escolhe o bloco pelo nome, explicado em como o nginx escolhe o site pelo nome do host. Teste com sudo nginx -t antes de recarregar.
Testando as quatro combinações
for u in http://oficinadocodigo.com.br http://www.oficinadocodigo.com.br \
https://oficinadocodigo.com.br https://www.oficinadocodigo.com.br; do
curl -s -o /dev/null -w '%{http_code} %{url_effective} -> %{redirect_url}\n' "$u/precos?plano=anual"
done
A saída esperada é três 301 apontando para o mesmo endereço e um 200:
301 http://oficinadocodigo.com.br/precos?plano=anual -> https://oficinadocodigo.com.br/precos?plano=anual
301 http://www.oficinadocodigo.com.br/precos?plano=anual -> https://oficinadocodigo.com.br/precos?plano=anual
200 https://oficinadocodigo.com.br/precos?plano=anual ->
301 https://www.oficinadocodigo.com.br/precos?plano=anual -> https://oficinadocodigo.com.br/precos?plano=anual
Se algum redirect_url aponta para um endereço que também redireciona, você tem uma cadeia. O guia cadeia de redirect gasta a paciência e a busca mostra como encontrar e achatar.
HSTS, cookies e canonical depois da troca
Com tudo em HTTPS, o cabeçalho Strict-Transport-Security faz o navegador ir direto para HTTPS nas próximas visitas. Comece com um tempo curto e só aumente depois de confirmar que tudo funciona; cuidado especial com includeSubDomains e com a lista de preload, que valem para subdomínios que talvez ainda não tenham HTTPS e são difíceis de desfazer.
Nos cookies de sessão, com um único host canônico, o cookie sem Domain passa a funcionar sempre, porque todo mundo termina no mesmo lugar. E a tag canonical de cada página deve apontar para a URL completa no host escolhido, respondendo 200, como detalha canonical aponta para a URL que você quer na busca.
Erros comuns
- Deixar os dois hosts respondendo 200. A busca vê conteúdo duplicado, links se dividem e a sessão se perde na troca.
- Certificado só para um nome. Quem digita o outro vê erro de segurança antes de chegar ao redirecionamento.
- Redirecionar em dois saltos.
http://wwwvai parahttps://wwwe só depois para o apex. Funciona, mas cada salto é latência e chance de erro. - Redirecionar tudo para a home. O link antigo para
/precoscai na página inicial, e a pessoa e a busca perdem a página certa. - Usar 302 numa troca permanente. O 302 diz que a mudança é temporária, e a busca pode continuar tratando o endereço antigo como o principal.
- Canonical e sitemap no host errado. O seu próprio site manda sinais contraditórios sobre qual endereço vale.
Checklist
- Existe uma decisão escrita de qual host é o canônico.
- Os dois nomes resolvem no DNS para o servidor.
- O certificado cobre os dois nomes.
- As três combinações não canônicas respondem 301 em um salto para o HTTPS do host escolhido.
- Caminho e query string são preservados no redirecionamento.
- Canonical, sitemap e links internos usam só o host escolhido.
- O teste com curl das quatro combinações foi rodado depois do último deploy.
Rode o laço de curl acima trocando pelo seu domínio. As quatro linhas terminam no mesmo endereço, com três 301 e um 200, ou alguma delas ainda responde 200 no host que você não escolheu?
Referência: https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls