Desenvolvimento e IA Aplicada · Tutorial

Como automatizar auditorias técnicas de SEO

Uma auditoria técnica feita uma vez por trimestre envelhece no dia seguinte. Veja como dividir as verificações em camadas que rodam sozinhas a cada publicação e falham antes de o problema chegar ao buscador.

Editor responsável:
Daniel Ferreira

Publicado em · 8 min de leitura

Também disponível em: English

Em três pontos

  • Regras objetivas, como título, canonical, noindex e sitemap, cabem num script que roda sobre o site gerado e bloqueia a publicação.
  • Lighthouse CI mede desempenho e boas práticas em laboratório; os dados de usuários reais vêm de outras fontes e mudam devagar.
  • Automação não substitui julgamento: ela confere a presença de elementos, não a qualidade do conteúdo nem o ranqueamento.

Uma mudança no template remove a meta description de todas as páginas de categoria. Outra marca como noindex uma seção inteira por engano. Nenhuma das duas quebra o site, e as duas podem passar semanas sem ninguém notar.

Uma auditoria técnica de SEO é a verificação dos elementos que permitem a um buscador encontrar, ler e indexar suas páginas: títulos, descrições, canonical, diretivas de indexação, sitemap, links, desempenho. Feita à mão, ela vira um relatório que envelhece rápido. Automatizada, vira um teste que roda a cada publicação.

Este tutorial organiza a automação em quatro camadas, da mais barata à mais lenta, e termina com o caso do próprio Token & Tech.

As quatro camadas

Nem toda verificação precisa rodar no mesmo momento. Na avaliação da redação, uma divisão prática é esta:

  1. Regras estáticas sobre o build. Conferências objetivas no HTML gerado: existe título, existe descrição, a canonical está certa, não há noindex onde não deveria. Rodam em segundos e devem bloquear a publicação.
  2. Auditoria de laboratório. O Lighthouse carrega páginas num navegador controlado e mede desempenho, acessibilidade, boas práticas e SEO. Roda em minutos, sobre uma amostra de páginas.
  3. Dados de campo. Métricas de usuários reais, que só existem depois da publicação e mudam ao longo de semanas.
  4. Estado no índice. O que o Google de fato indexou, consultado pela API do Search Console.

As camadas 1 e 2 entram no pipeline de publicação. As camadas 3 e 4 são monitoramento: rodam em agenda e geram alertas, não bloqueios.

Camada 1: um script sobre o site gerado

Comece pelo que é objetivo e barato. Para um site estático, o build produz uma pasta de HTML. Um script lê o sitemap, abre o arquivo de cada URL e confere uma lista de regras. Se encontrar erro, termina com código de saída diferente de zero, e o processo de publicação para.

Regras que costumam valer para qualquer site:

  • Título presente, não vazio e sem duplicata no mesmo idioma.
  • Meta description presente e não vazia. A própria documentação do Lighthouse avisa que a auditoria dele só verifica isso e “não avalia a qualidade” do texto. Um limite de tamanho, se você quiser, é regra sua.
  • Canonical igual à URL publicada no sitemap.
  • Nenhuma página do sitemap com noindex. O Google aceita a diretiva tanto na tag <meta name="robots"> quanto no cabeçalho HTTP X-Robots-Tag, e ela só funciona se a página não estiver bloqueada no robots.txt, porque o robô precisa acessá-la para ler a regra (Google Search Central). Uma página no sitemap e com noindex ao mesmo tempo é quase sempre um erro de configuração.
  • Um único H1 por página, se essa for a convenção do seu site.
  • Links internos que apontam para arquivos existentes. O passo a passo dessa parte está em Como testar links internos e rotas automaticamente.

Um esqueleto mínimo, apenas como exemplo, em Node.js sem dependências:

// exemplo: check-seo.mjs: roda depois do build
import { readFileSync, existsSync } from "node:fs";

const SITE = "https://example.com";
const errors = [];
const sitemap = readFileSync("dist/sitemap.xml", "utf8");
const urls = [...sitemap.matchAll(/<loc>([^<]+)<\/loc>/g)].map((m) => m[1]);

for (const url of urls) {
  const file = `dist${url.slice(SITE.length)}index.html`;
  if (!existsSync(file)) { errors.push(`sem arquivo: ${url}`); continue; }
  const html = readFileSync(file, "utf8");
  if (!/<title>[^<]{10,}<\/title>/.test(html)) errors.push(`${url}: título`);
  if (!/<meta name="description" content="[^"]+"/.test(html)) errors.push(`${url}: description`);
  if (!html.includes(`<link rel="canonical" href="${url}"`)) errors.push(`${url}: canonical`);
  if (/<meta name="robots" content="[^"]*noindex/.test(html)) errors.push(`${url}: noindex no sitemap`);
}

if (errors.length) { console.error(errors.join("\n")); process.exit(1); }
console.log(`OK: ${urls.length} URLs`);

As expressões regulares acima dependem do formato exato do HTML que o seu gerador produz. Para HTML menos previsível, um analisador de HTML é mais seguro.

Duas observações. Primeiro, o script só enxerga o HTML: um X-Robots-Tag configurado no servidor não aparece aqui, e precisa ser conferido com requisições ao site publicado. Segundo, separe erros de avisos. Erro bloqueia; aviso, como uma descrição longa demais, aparece no log e não impede a publicação.

Camada 2: Lighthouse CI

O Lighthouse é uma ferramenta automatizada de código aberto do Google que audita páginas em desempenho, acessibilidade, SEO e outras categorias. Pode rodar no DevTools do Chrome, na linha de comando, como módulo Node.js ou pelo PageSpeed Insights (visão geral).

O Lighthouse CI é a versão feita para integração contínua. Segundo o guia de início, o comando lhci autorun coleta resultados, aplica asserções e envia os relatórios. Para sites estáticos, a opção staticDistDir aponta para a pasta do build, onde estão os HTML a auditar. Para sites com servidor próprio, as opções startServerCommand e url indicam como subir o servidor e quais páginas testar.

Uma configuração mínima, apenas como exemplo:

// exemplo: lighthouserc.js
module.exports = {
  ci: {
    collect: { staticDistDir: "./dist", numberOfRuns: 3 },
    assert: {
      assertions: {
        "categories:seo": ["error", { minScore: 0.9 }],
        "categories:performance": ["warn", { minScore: 0.8 }],
      },
    },
    upload: { target: "filesystem" },
  },
};

Pontos da documentação de configuração que mudam o resultado:

  • Nível da asserção. warn imprime a falha mas não altera o código de saída; error faz o processo terminar com código diferente de zero. É essa diferença que decide se a falha bloqueia a publicação.
  • Número de execuções. O padrão é 3 execuções por URL, porque medidas de laboratório oscilam. O método de agregação padrão é optimistic, que usa o valor “mais provável de passar” entre as execuções. Se você quer uma régua mais exigente, existem median e pessimistic.
  • Destino dos relatórios. A opção temporary-public-storage é a mais simples, mas a documentação a recomenda só se você aceita que os relatórios fiquem acessíveis a qualquer pessoa com o link. Para projetos privados, prefira filesystem ou um servidor próprio.

Uma dica do próprio guia: em sites com muitos problemas, ligue as asserções aos poucos, tratando as falhas como lista de tarefas. Um teste que falha sempre acaba desligado.

E um limite importante. A nota de SEO do Lighthouse soma auditorias de presença: a página bloqueia indexação? Tem description? Cada auditoria de SEO tem o mesmo peso na nota, segundo a documentação. Nota 100 significa que os requisitos técnicos verificados estão presentes. Não significa que a página vai ranquear.

Camada 3: dados de campo, em agenda

O Lighthouse mede em laboratório: um dispositivo, uma rede e um local definidos, para que o resultado seja reproduzível. Os dados de campo vêm de usuários reais, normalmente do Chrome User Experience Report (CrUX), e formam uma distribuição. O web.dev recomenda usar dados de campo para priorizar e de laboratório para depurar e testar mudanças antes de publicar.

As três Core Web Vitals e seus limites de “bom”, medidos no percentil 75 das visitas, são (web.dev):

  • LCP (Largest Contentful Paint, tempo até o maior elemento visível carregar): até 2,5 segundos.
  • INP (Interaction to Next Paint, tempo de resposta às interações): até 200 milissegundos.
  • CLS (Cumulative Layout Shift, quanto o layout se desloca): até 0,1.

O Lighthouse não mede INP, porque no laboratório não há interação real. Ele usa o Total Blocking Time (TBT) como indicador aproximado. Uma página pode ter TBT bom e INP ruim.

Para consultar esses números automaticamente, a API do PageSpeed Insights devolve o resultado do Lighthouse e, quando há dados, as métricas de campo. A chave de API é opcional, mas recomendada para consultas automáticas frequentes. A mesma página informa que o Google planeja deixar de incluir os dados do CrUX nessa API e indica a API do CrUX no lugar. Se você está começando agora, vale montar a consulta de campo já sobre ela.

Como dados de campo mudam devagar, rodar essa camada a cada publicação não faz sentido. Uma consulta semanal, gravada num arquivo ou planilha, mostra a tendência.

Camada 4: o que o Google indexou

A última camada responde à pergunta que as outras não respondem: o Google indexou a página, e com qual canonical? O método urlInspection.index.inspect da API do Search Console devolve o status de uma URL na versão que está no índice. A própria documentação avisa que, por enquanto, só esse status está disponível: não é possível testar pela API a indexabilidade da URL ao vivo.

A chamada exige autenticação OAuth com acesso à propriedade no Search Console e o escopo webmasters ou webmasters.readonly. Use o de leitura. Guarde a credencial no cofre de segredos da sua automação, nunca no repositório.

Um uso razoável: uma vez por semana, inspecionar uma amostra de URLs importantes e as publicadas recentemente, e alertar quando a canonical escolhida pelo Google divergir da declarada.

Onde cada camada roda

Junte as camadas assim:

  • A cada build, antes de publicar: camada 1 (bloqueia) e, se o tempo permitir, camada 2 sobre uma amostra de páginas-modelo, como a home, um artigo e uma categoria.
  • Em agenda: camadas 3 e 4, com alertas.
  • Ao vivo, logo depois de publicar: algumas requisições ao site real para conferir status HTTP, redirecionamentos e cabeçalhos que o build não mostra.

Como ligar tudo isso a uma publicação automática e segura é o assunto de Como configurar deploy automático com segurança.

Caso documentado: a auditoria do Token & Tech

O site que você está lendo usa a camada 1 como trava de publicação. O script scripts/check-dist.mjs, chamado por npm run check, roda sobre a pasta gerada pelo build e não usa dependências externas.

Para cada URL do sitemap, ele confere que o arquivo existe e que a página tem <html lang> compatível com o idioma, título com tamanho mínimo e sem duplicata no mesmo idioma, description, canonical igual à URL, exatamente um H1 e imagem de compartilhamento existente. Uma página do sitemap com noindex é erro. Depois, cruza o hreflang: cada versão precisa citar a si mesma, ter x-default e receber o link de volta.

O script também confere que o robots.txt aponta para o sitemap, que arquivos obrigatórios existem e que arquivos de configuração e de dados não foram parar na pasta publicada. Título acima de 70 caracteres e description acima de 165 geram aviso, não erro.

Se houver qualquer erro, o script lista todos e termina com código 1. O script de publicação só segue adiante se o build e essa checagem passarem. O site não usa Lighthouse CI no pipeline; as camadas 2 a 4 ficam fora do processo automático descrito aqui.

O que levar deste texto

  • Separe a auditoria em camadas: regras estáticas e laboratório na publicação, dados de campo e índice em agenda.
  • Faça a camada 1 primeiro. É barata, objetiva e pega os erros mais caros, como noindex ou canonical errados.
  • No Lighthouse CI, só error bloqueia. Use warn para o que ainda está sendo corrigido e não publique relatórios de projeto privado em armazenamento público.
  • Trate a nota do Lighthouse como checagem de requisitos, não como previsão de ranqueamento.

Divulgação: O site do Token & Tech usa as técnicas descritas aqui.

Fontes

  1. Block Search indexing with noindex, Google Search Central. Acesso em 8 de outubro de 2026
  2. Why lab and field data can be different (and what to do about it), web.dev (Google). Acesso em 8 de outubro de 2026
  3. Configuration (Lighthouse CI), GoogleChrome/lighthouse-ci (GitHub). Acesso em 8 de outubro de 2026
  4. Getting Started (Lighthouse CI), GoogleChrome/lighthouse-ci (GitHub). Acesso em 8 de outubro de 2026
  5. Page is blocked from indexing, Chrome for Developers (Google). Acesso em 8 de outubro de 2026
  6. Document doesn't have a meta description, Chrome for Developers (Google). Acesso em 8 de outubro de 2026
  7. Introduction to Lighthouse, Chrome for Developers (Google). Acesso em 8 de outubro de 2026
  8. Get Started with the PageSpeed Insights API, Google for Developers. Acesso em 8 de outubro de 2026
  9. Method: urlInspection.index.inspect (Search Console API), Google for Developers. Acesso em 8 de outubro de 2026
  10. Web Vitals, web.dev (Google). Acesso em 8 de outubro de 2026

Leia também

Desenvolvimento e IA Aplicada · Explicador

Content Collections do Astro: conteúdo em escala

Quando um site passa de algumas páginas para centenas de textos, o problema deixa de ser escrever e passa a ser manter tudo consistente. Veja como o Astro resolve isso com coleções tipadas.

Desenvolvimento e IA Aplicada · Explicador

Astro: por que usar em sites com milhares de páginas

Quando um site tem milhares de páginas de conteúdo, cada decisão de arquitetura se multiplica. Veja, pela documentação oficial e por dados de campo datados, o que o Astro faz bem nesse cenário e onde estão os limites.

Desenvolvimento e IA Aplicada · Análise

Astro ou Next.js: arquitetura e desempenho comparados

Astro e Next.js geram HTML no servidor, mas partem de premissas diferentes: um nasceu para sites de conteúdo, o outro para aplicações React. Veja, com documentação oficial e dados de campo datados, o que isso muda na prática.