Página 404 que ajuda a pessoa e devolve 404 de verdade (não 200)
Monte uma página de "não encontrado" que oferece caminho de volta e responde com status 404, evite o soft 404 em Express, Nginx e SPA, e confira tudo com curl.
O endereço antigo de um artigo mostra uma página bonita: "Ops, não encontramos o que você procura". O designer caprichou. Só que o servidor respondeu 200 OK, e a busca indexou a mensagem de erro como se fosse conteúdo, em 300 URLs diferentes. A resposta curta: a página de erro pode ser amigável, mas o status HTTP precisa ser 404. Texto humano, caminho de volta e o código certo, as duas coisas juntas.
O visual engana porque a pessoa vê a mensagem e entende. Quem não vê a mensagem, só o status, é o robô da busca, o monitoramento e qualquer ferramenta de link quebrado. Para eles, 200 quer dizer "esta página existe e está ótima".
Por que o status errado vira um problema
A documentação do Google sobre erros HTTP chama esse caso de soft 404: uma página que diz ao visitante que não existe, mas responde como se existisse. O Google tenta detectar isso pelo conteúdo e, quando detecta, lista a URL como soft 404 no relatório de indexação do Search Console. Quando não detecta, a página de erro pode ir parar no índice.
Os efeitos práticos:
- Rastreamento desperdiçado. O robô volta periodicamente a centenas de URLs que respondem 200 com o mesmo texto de erro.
- Link quebrado invisível. Seu monitoramento e seu verificador de links não acusam nada, porque nada responde erro.
- Métrica falsa. A análise de tráfego conta visitas a "páginas" que não existem.
Se você precisa revisar o que cada código significa, veja os códigos de status HTTP que importam no dia a dia.
404, 410 ou redirecionamento?
Três casos diferentes, três respostas diferentes:
- Nunca existiu ou não se sabe: 404.
- Existiu e foi removido de propósito, sem substituto: 410 (Gone) comunica isso de forma mais explícita. O Google trata 404 e 410 de forma parecida, então 404 também está correto.
- Mudou de endereço: 301 para a URL nova, que é o assunto do guia sobre redirecionar URL do jeito certo.
O que não se faz: redirecionar todo endereço inexistente para a home. A pessoa procurava um artigo, cai na capa e não sabe o que aconteceu. A busca tende a tratar isso como soft 404 do mesmo jeito.
Como montar a página 404 que ajuda
- Diga o que aconteceu, em uma frase. "Não encontramos esta página." Sem piada que esconde a informação.
- Ofereça a busca já preenchida. Transforme o slug da URL em termos:
/blog/backup-mysql-restaurarvira "backup mysql restaurar" na caixa de busca. - Dê dois ou três caminhos. A home, as categorias principais e, se possível, os posts mais lidos.
- Mantenha o layout do site. Cabeçalho e menu normais mostram que a pessoa ainda está no lugar certo.
- Responda 404 no servidor. É o passo que mais se esquece e o único que a busca enxerga.
Em Express
app.get('/blog/:slug', async (req, res, next) => {
try {
const post = await buscarPostPublicado(req.params.slug);
if (!post) {
return res.status(404).render('404', {
termos: req.params.slug.split('-').join(' '),
});
}
res.render('post', { post });
} catch (err) {
next(err);
}
});
// Depois de todas as rotas: qualquer caminho que sobrou é 404
app.use((req, res) => {
res.status(404).render('404', { termos: '' });
});
Dois pontos. Primeiro, o caso "slug não existe no banco" precisa do 404 explícito: o handler genérico do fim nunca é alcançado, porque a rota /blog/:slug casou. Segundo, erro de banco não é 404. Ele vai para o next(err) e vira 500, que é a verdade.
Em Nginx servindo arquivos estáticos
server {
listen 443 ssl;
server_name www.exemplo.com.br;
root /var/www/site;
error_page 404 /404.html;
location = /404.html {
internal;
}
location / {
try_files $uri $uri/ =404;
}
}
O =404 no try_files faz o Nginx devolver o status certo quando o arquivo não existe, e o error_page entrega o conteúdo amigável com esse mesmo status. O internal impede que /404.html seja acessada diretamente com 200.
Cuidado com a variação comum try_files $uri /index.html;. Ela serve o index para qualquer caminho, com 200. É assim que nasce o soft 404 em massa.
Em aplicação de página única
Em SPA, o servidor costuma devolver o mesmo HTML para todas as rotas, e quem descobre que a rota não existe é o JavaScript. A documentação do Google sobre JavaScript e SEO sugere duas saídas: redirecionar, pelo JavaScript, para uma URL em que o servidor responde 404, ou incluir <meta name="robots" content="noindex"> na tela de erro. A melhor solução continua sendo o servidor saber quais rotas existem e responder 404 por conta própria, o que frameworks com renderização no servidor fazem.
Como conferir o status de verdade
Não confie no olho. Invente um slug e peça só o código:
curl -s -o /dev/null -w "%{http_code}\n" https://www.exemplo.com.br/blog/slug-que-nao-existe-123
A saída precisa ser 404. Faça o teste em três lugares: um slug de post inexistente, um caminho fora de qualquer rota (/qualquer/coisa) e um arquivo estático inexistente (/img/nao-existe.png). Cada um costuma passar por um caminho diferente no código, e o erro mora em um deles.
Depois, use os 404 como fonte de trabalho. Registre a URL pedida e o cabeçalho Referer. Um 404 vindo do seu próprio domínio é link interno quebrado, e corrigir o link vale mais do que caprichar na página de erro.
Erros comuns
- Página de erro com 200. A busca pode indexar a mensagem, e seu monitoramento não enxerga links quebrados.
- Redirecionar tudo para a home. A pessoa perde o contexto, e a busca tende a tratar como soft 404 de qualquer forma.
- Erro de banco virando 404. Uma queda do banco faz o site inteiro "sumir" para a busca, quando o certo seria 500 ou 503 temporário.
- Fallback de SPA no servidor sem exceção.
try_filespara o index em todo caminho, inclusive em/img/e/api/, que deveriam responder 404 de verdade. - Página 404 sem saída. Só a mensagem e nada mais. A pessoa fecha a aba.
- Página 404 pesada. Ela é servida para robôs e bots de varredura o tempo todo. Se cada 404 faz dez consultas ao banco, o erro vira carga.
Checklist
curlnum slug inventado devolve 404.- Um caminho fora de qualquer rota devolve 404.
- Um arquivo estático inexistente devolve 404.
- Falha de banco devolve 5xx, não 404.
- A página tem busca preenchida com os termos do slug e links para a home e categorias.
- Conteúdo que mudou de endereço responde 301 para a URL nova.
- Os 404 com Referer do seu domínio são revisados e os links corrigidos.
Para fechar: rode o curl agora num endereço que você acabou de inventar no seu site. O número que voltou foi 404 ou 200?
Referência: https://developers.google.com/search/docs/crawling-indexing/http-network-errors