A 27 de setembro de 2026, Joost de Valk publicou um texto sobre o facto de quase ninguém fazer sitemaps XML corretamente. Com o plugin Sitemap Inspector analisou seis sites, da Adobe ao GOV.UK, e em todos encontrou o mesmo: endereços com noindex, redirecionamentos, 404, canónicos a apontar para outro lado, uma única data para centenas de entradas. A tese dele é: “A sitemap should list the URLs a site wants indexed, and nothing else.”
Concordamos com a tese e com a lista. Usámo-la para verificar o nosso próprio site. Entre agosto e outubro de 2026 encontrámos no gerador de sitemaps de wppoland.com cinco erros, cada um medido em produção. Três deles a lista de Joost apanharia. Dois não os apanha nenhum inspetor que leia as entradas do sitemap, porque consistiam naquilo que lá não estava. Este texto trata dos dois tipos.
Contexto técnico: wppoland.com é um site Astro em seis idiomas, com cerca de 6700 endereços nos sitemaps. Os sitemaps são gerados por uma integração própria, astro-sitemaps.mjs, e não por um plugin. Isto é importante para as conclusões: cada um dos erros abaixo estava no código que lê os dados e constrói a lista, e não na lista em si.
Erro 1: a data do build como lastmod
A 24 de agosto de 2026, cinco sitemaps diferentes tinham exatamente um valor de lastmod para todas as entradas, o mesmo, o de hoje. A integração calculava new Date() uma vez e carimbava com ele 3079 endereços. Cada implementação anunciava ao Google que tudo tinha mudado.
O Google descreve a condição sem rodeios: usa o <lastmod> se o valor corresponder de forma “consistently and verifiably” à última alteração da página (Google Search Central, página sobre a criação de sitemaps, atualização de 8 de julho de 2026). Uma data que salta a cada build não cumpre essa condição, por isso o Google deixa de confiar nela em todo o domínio, incluindo onde seria verdadeira. Nas amostras desse período, o último rastreio de algumas páginas recuava de três semanas a três meses.
A correção passou a usar updatedDate do frontmatter e, na sua falta, pubDate. Efeito no artefacto: o sitemap polaco do blog passou de 1 para 98 datas diferentes.
Nesta correção é fácil cometer um erro de segunda ordem. Era tentador usar o campo lastVerified nas páginas de cidades, porque todos os 4733 ficheiros o têm. Só que 4697 dos 4733 ficheiros têm nele o mesmo valor. É um carimbo em massa, não um sinal, e transferiria o mesmo defeito de “hoje” para outra data fixa. Antes de qualquer campo de data ir parar ao lastmod, é preciso contar quantos valores diferentes tem.
A correção de agosto abrangeu o blog, o portfólio e as páginas das coleções de conteúdo. Não abrangeu as rotas .astro escritas à mão. O artigo de Joost levou-nos a verificar de novo: a 29 de setembro, em /pl/sitemap-pages.xml, 62 de 113 endereços continuavam a ter como lastmod a data do build, porque não existe para eles uma data no conteúdo e o código recorria então a today. A correção (commit af97c7a887) usa para essas rotas a data do último commit do ficheiro de origem, obtida numa única chamada a git log por build, e, quando nem essa existe, omite o lastmod. O template partilhado [lang]/[slug].astro não conta deliberadamente como origem, porque a sua data não diz nada sobre nenhuma página concreta. O mesmo ficheiro depois da correção: 87 de 113 endereços têm lastmod, 42 datas diferentes, e a mais frequente aparece em 7 endereços, enquanto 26 endereços não têm data nenhuma. No sitemap polaco das páginas de cidades, antes da correção 684 de 692 entradas tinham a data do build; depois dela, 8 entradas têm uma data verdadeira: o template das cidades não tem uma data que se possa usar honestamente, por isso as restantes não declaram data. A correção está em produção desde 29 de setembro de 2026, e o ficheiro em produção mostra os mesmos números.
Erro 2: o filtro de noindex vigiava um único campo
Depois de passarmos 723 páginas de cidades para noindex, o Search Console continuava a apresentá-las como descobertas. As páginas em si tinham o noindex correto. Voltavam ao Google por outro caminho: o sitemap-locations.xml listava-as como alternativas de idioma (xhtml:link, incluindo x-default) de páginas que tinham ficado no índice.
O filtro de noindex da integração verificava apenas o <loc>. As alternativas vêm do cabeçalho da página, que lista todas as versões de idioma, por isso o filtro não as via. A correção mantém só as alternativas cujo endereço é, ele próprio, um <loc> no sitemap. Depois dela, o build produzia 6407 endereços e 0 alternativas erradas.
A conclusão vai além dos sitemaps: um filtro aplicado a um campo de uma entrada não cobre os outros campos dessa entrada que transportam um endereço. Num sitemap há vários desses sítios: loc, as alternativas, x-default, image:loc.
Erro 3: 500 páginas funcionais fora do sitemap
A 21 de setembro de 2026, a integração começou a omitir todos os endereços que correspondessem aos prefixos que o middleware em functions/_middleware.ts redireciona. Só que o middleware redireciona-os apenas quando o recurso devolve 404, e cada candidato ao sitemap é uma página construída, que por isso nunca devolve 404. O filtro copiou a regra sem a sua condição.
Resultado: 500 páginas funcionais com index, follow saíram do sitemap, incluindo o destino de um dos redirecionamentos (/pl/audyt-bezpieczenstwa-wordpress/ correspondia ao prefixo audyt-bezpieczenstwa-). A correção entrou a 26 de setembro e o build com o sitemap deu +500 endereços e 0 removidos.
Nenhuma verificação de entradas apanha este erro. Cada um dos endereços que restavam estava correto: era renderizado, não tinha noindex, não redirecionava. Menos endereços no sitemap parece arrumação, não um defeito. Só se deteta comparando o conjunto de endereços antes e depois da alteração.
Erro 4: >- como endereço de imagem
A integração extraía o heroImage do frontmatter com uma expressão regular, linha a linha. Com um bloco dobrado de YAML (heroImage: >-), o valor fica na linha seguinte, por isso a regex apanhava o >- literal. O sitemap recebia entradas <image:loc>https://wppoland.com/>-</image:loc>.
A 17 de setembro de 2026 havia em produção 31 entradas destas em seis idiomas. O Search Console mostrava cinco erros em pl/sitemap-blog.xml, e no entanto o XML estava bem formado e cada <loc> estava em ordem. O YAML nos ficheiros também estava correto. O que estava avariado era o leitor.
A correção lê o frontmatter com um parser de YAML, e exportámos da integração a função que extrai os metadados, para que um teste lhe pudesse chegar sem um build completo. Antes, estava no meio de um ficheiro de 900 linhas e nenhum teste tinha acesso a ela.
Erro 5: o IndexNow enviava endereços que não existem
O script para o IndexNow construía os endereços a partir dos nomes de ficheiros em src/content/. A 17 de setembro de 2026 gerava 2328 endereços, dos quais 0 constavam do sitemap. As entradas do blog recebiam um segmento /blog/ que não existe nos endereços, e as páginas mantinham o sufixo de idioma do nome do ficheiro (/de/about.de/). Ambas as variantes devolviam 301. Além disso, o padrão de ficheiros só apanhava .md, por isso 100 pilares de serviço em .mdx nunca eram enviados.
A correção cabe numa frase: a fonte de endereços para o IndexNow é o sitemap-index.xml. Esse conjunto já está verificado: as páginas são renderizadas e não têm noindex. A heurística baseada em nomes de ficheiros desapareceu, e com ela três classes de erros.
Um erro sem erro: o Google não descarregou o sitemap
Este caso não foi um defeito do gerador, mas pertence à mesma família. No início de setembro de 2026, depois de desbloquearmos as páginas de cidades, os seis sitemaps de localizações somavam 4071 endereços. Do nosso lado estava tudo correto: as amostras devolviam 200 e index, follow, e nenhum endereço do sitemap tinha noindex nem era um redirecionamento.
O Search Console descarregou estes sitemaps pela última vez a 1 de setembro às 10:08, quando tinham 2037 endereços, e durante cinco dias não os atualizou. Os sitemaps do blog eram lidos todos os dias. Tudo o que foi acrescentado depois dessa hora não existia para o Google. Um novo envio através da API foi descarregado no mesmo dia.
Na semana seguinte, o número de páginas de cidades com impressões subiu de 223 para 343, e as impressões delas de 1570 para 4382. Essas 343 páginas são 8,4 por cento de 4071 e em sete dias trouxeram 2 cliques. O que se desbloqueou foi a descoberta, não o tráfego, e são dois números diferentes.
O que o inspetor de entradas não vê
| Erro | Como aparecia no sitemap | A verificação de entradas deteta-o? | O que o detetou |
|---|---|---|---|
| Data do build como lastmod | todas as entradas com uma única data | sim, como lastmod repetido | número de datas diferentes no ficheiro |
| Alternativas ao lado de noindex | <loc> corretos, xhtml:link errados | em parte, se verificar as alternativas | relatório de noindex do Search Console |
| 500 páginas fora do sitemap | cada entrada presente correta | não | comparação do conjunto de endereços antes e depois |
>- como imagem | 31 image:loc errados | sim, se verificar as imagens | erros de sitemap no Search Console |
| IndexNow fora do sitemap | sitemap correto | não, o erro está fora do sitemap | interseção da lista de envio com o sitemap |
| Sitemap não descarregado | ficheiro correto e atualizado | não | data de leitura no Search Console |
Um plugin como o que Joost usou responde à pergunta “o que está no sitemap está correto?”. É uma boa pergunta e a maioria dos sites, como ele mostrou, não lhe responde. Mas três dos nossos seis casos tratavam de outra coisa: o que não está no sitemap, o que o utiliza e que versão o Google vê.
Lista de verificação para o gerador de sitemaps
A verificação das entradas é condição necessária, não suficiente. Estes cinco pontos verificam o gerador, e não apenas o ficheiro:
- Conte os valores diferentes de
lastmodem cada ficheiro. Um único valor para centenas de entradas é um carimbo, não uma data. O mesmo antes de usar um novo campo de data: se quase todos os ficheiros têm nele o mesmo valor, o campo não serve paralastmod. Não terlastmodé melhor do que ter um falso. - Compare o conjunto de endereços antes e depois de uma alteração ao gerador. Número de endereços acrescentados e removidos, com a lista. Uma descida no número de endereços exige explicação tal como uma subida.
- Todos os campos que transportam um endereço passam pelos mesmos filtros.
loc, alternativas de idioma,x-default,image:loc. Um filtro num deles não protege os restantes. - Uma regra copiada de outro componente vem acompanhada da sua condição. Um redirecionamento “quando 404” não é o mesmo que um redirecionamento sempre.
- O sitemap é a única fonte de endereços para tudo o que envia endereços para fora: IndexNow, Indexing API, listas para submissão manual. E uma vez por semana: a data da última leitura no Search Console e o número de endereços que lá aparece, ao lado do número de
<loc>no ficheiro em produção.
Duas coisas da documentação do Google que convém ter à mão: um ficheiro de sitemap comporta no máximo 50 000 endereços ou 50 MB sem compressão, e os valores de <priority> e <changefreq> são ignorados. Não prejudicam, mas não vale a pena trabalhar neles.
Se o site funciona como WordPress headless, surge a pergunta de quem gera afinal o sitemap, o front-end ou o WordPress. Descrevemos isso à parte no texto sobre sitemap e endereço canónico em WordPress headless.







