SEO para Cloudflare Workers

Como fazer mudanças técnicas de SEO no Cloudflare Workers — o handler fetch, o HTMLRewriter para injetar canonical/hreflang/JSON-LD, redirecionamentos apoiados por KV, a Cache API versus o cache de borda versus Cache-Control, a fronteira do cloaking e como o Bot Fight Mode pode bloquear o Googlebot.

Publicado pela primeira vez: 3 de jul. de 2026 · Última atualização: 3 de ago. de 2026 · Avançado
Idiomas
1 sinal de evidência nesta página

SEO para Cloudflare Workers é fazer SEO técnico no runtime serverless da Cloudflare: um Worker só vê as solicitações correspondentes à sua rota, e cada uma entra em um único handler fetch onde você reescreve a solicitação, os headers da resposta e o corpo da resposta. A reescrita do corpo passa pelo HTMLRewriter — o mecanismo real para injetar uma canonical, corrigir hreflang ou adicionar JSON-LD sem uma implantação do CMS — e precisa ser idempotente para casos ausentes, duplicados e não HTML. Redirecionamentos em escala pertencem ao KV ou D1; Bulk Redirects/Rules são mais simples para conjuntos pequenos, mas escolha um responsável por URL para que os sistemas não entrem em conflito. Três coisas diferentes compartilham a palavra cache — a Workers Cache API, o cache de borda da Cloudflare e o Cache-Control da origem — e confundi-las é o motivo de uma tag injetada parecer não aparecer; diagnostique por chave de cache, camada, TTL e invalidação. A regra absoluta é o cloaking: aplique lógica idêntica ao Googlebot e aos usuários. O problema mais específico dos Workers causado pelo próprio operador é o Bot Fight Mode bloquear o Googlebot em um pipeline ao qual as regras de permissão do WAF nem chegam. Publique toda mudança que afete SEO com metadados de versão registrados e um rollback testado, depois verifique com a inspeção de URL do GSC e o header CF-Cache-Status. Consulte o hub de Edge SEO para o conceito geral.

TL;DR — Um Cloudflare Worker só vê solicitações correspondentes à sua rota configurada e intercepta cada uma em um único handler fetch, onde você faz três coisas em sequência: reescreve a solicitação, reescreve os headers da resposta e reescreve o corpo da resposta por meio de HTMLRewriter. Esse é o mecanismo real por trás de “injetar uma canonical” ou “corrigir um título” — e ele precisa ser idempotente, testado contra respostas ausentes, duplicadas e não HTML, não apenas contra o caminho feliz. Redirecionamentos em escala ficam em KV (consulta rápida por chave) ou D1 (relacional); Bulk Redirects/Rules cobrem conjuntos pequenos de forma mais simples, e em geral prefiro redirecionamentos no nível da borda aos do servidor — mas escolha um único responsável por cada URL, porque um redirecionamento do Worker, um Bulk Redirect e um redirecionamento da origem podem ser acionados no mesmo caminho. Três coisas diferentes compartilham a palavra “cache” — a Workers Cache API (caches.default), o cache de borda da Cloudflare e o Cache-Control da origem — e confundi-las é a causa habitual de “minha tag não apareceu”; diagnostique a obsolescência pela chave, camada, TTL e invalidação do cache, em vez de adivinhar. A orientação do próprio Google sobre ETag / If-None-Match / 304 é diretamente acionável para um Worker que controla a resposta. A linha do cloaking: lógica idêntica para cada solicitante. A ferida mais específica dos Workers é o Bot Fight Mode, que roda fora do WAF Ruleset Engine, então regras comuns de “allow” nem chegam a ele. Publique toda mudança que afete SEO com metadados de versão registrados, rollback testado e uma condição de parada — depois verifique com a inspeção de URL do GSC e CF-Cache-Status.

O que este artigo é (e não é)

Este é o complemento prático e focado em código do hub de Edge SEO. O hub é responsável pela definição geral, pela tabela de comparação de plataformas (Workers, Akamai, Fastly, Lambda@Edge, Vercel, Netlify), pela decisão Snippets versus Workers e pelo tratamento completo da regra de cloaking. Não vou reproduzir nada disso aqui. Esta página aprofunda um nível nos Cloudflare Workers — o runtime usado pelo próprio Worker deste site, conectado por meio de run_worker_first em wrangler.toml — com APIs reais, não com generalidades de que “edge compute pode injetar tags”.

Uma observação antes do código: o Google não tem documentação específica de SEO para Cloudflare Workers. A orientação oficial que governa isso (política de cloaking, cache HTTP e rastreamento de CDNs) é geral e se aplica a qualquer implementação de borda. Prefiro dizer isso claramente a insinuar que existe um documento do Google que não existe.

Como um Worker se posiciona no caminho de solicitação/resposta

Um Worker é um script serverless executado em isolados V8. Toda solicitação encaminhada a ele entra por um handler fetch. Evidence for this claim A Cloudflare Worker receives HTTP requests through a fetch handler. Scope: Cloudflare Workers handlers. Confidence: high · Verified: Cloudflare Workers: Fetch handler “Encaminhada” faz um trabalho real nessa frase: um Worker só vê solicitações que correspondem à sua rota ou domínio personalizado configurado — todo o resto nunca chega ao handler fetch. Quando duas rotas podem corresponder à mesma URL, o padrão mais específico tem precedência; portanto, antes de confiar no comportamento de um Worker para uma URL, confirme que a rota realmente corresponde a ela e verifique qual versão implantada está ativa nessa rota (ambientes do Wrangler e lançamentos graduais significam que a versão que recebe tráfego nem sempre é a que está no seu editor). Dentro do handler, você pode fazer três coisas distintas, nesta ordem:

  1. Reescrever a solicitação antes que ela vá para sua origem.
  2. Reescrever os headers da resposta no caminho de volta.
  3. Reescrever o corpo da resposta — por meio de HTMLRewriter.

Esta é a forma mínima:

export default {
  async fetch(request, env, ctx) {
    // 1. (optionally) inspect/modify the request
    const response = await fetch(request);   // hit the origin

    // 2. rewrite headers
    const headers = new Headers(response.headers);
    headers.set("X-Robots-Tag", "index, follow");

    // 3. rewrite the body with HTMLRewriter (see next section)
    return new Response(response.body, { ...response, headers });
  },
};

A equipe da SALT.agency, que cunhou “edge SEO” a partir de pesquisas sobre Cloudflare Workers, construiu suas ferramentas como uma cadeia de filtros — um filtro de solicitação, um filtro de resposta e um filtro de corpo. É o mesmo padrão de três fases; eles apenas deram nomes a ele. Manter essas três fases separadas na sua cabeça torna um Worker legível.

Reescrevendo HTML com HTMLRewriter

HTMLRewriter é o parser de HTML em fluxo da Cloudflare e é a API real por trás de todo truque de “injetar uma tag”. Evidence for this claim Cloudflare HTMLRewriter provides selector-based handlers that can transform streamed HTML elements. Scope: Cloudflare Workers HTMLRewriter API. Confidence: high · Verified: Cloudflare Workers: HTMLRewriter Você registra handlers de elementos .on(selector, handler), e o handler recebe getAttribute / setAttribute, prepend / append, setInnerContent e replace. Como ele trabalha em fluxo, você não armazena o documento inteiro na memória.

Injetando ou corrigindo uma tag canonical

class CanonicalHandler {
  constructor(url) { this.url = url; }
  element(el) { el.setAttribute("href", this.url); }
}

const rewriter = new HTMLRewriter()
  .on('link[rel="canonical"]', new CanonicalHandler("https://example.com/preferred/"));

return rewriter.transform(response);

Se a página não tiver nenhuma canonical, anexe um handler a head e acrescente uma em vez de editar uma tag existente. De qualquer maneira, lembre-se da lição da parte de canonicalização: rel=canonical é uma dica, não um comando — um Worker permite defini-la de maneira consistente em toda uma plataforma, mas o Google ainda decide.

O CanonicalHandler acima presume que uma tag já existe e que a resposta é HTML. Nenhuma das duas coisas é garantida em produção, e errar é a forma de acabar com duas tags canonicals em uma página em vez de uma. Antes de publicar uma reescrita como esta, torne-a idempotente e teste-a contra:

  • Nenhuma canonical existente — seu handler precisa detectar a ausência e usar append para adicionar uma a head, não fazer nada silenciosamente porque link[rel="canonical"] não encontrou correspondência.
  • Uma canonical duplicada ou malformada já presente — decida se remove a tag excedente ou deixa a reescrita adicionar uma segunda (a última opção é um bug real, não um caso de borda — canonicals duplicadas são um problema comum criado pelo próprio site).
  • Uma resposta não HTML — uma rota de API, uma imagem ou uma resposta de redirecionamento passada pelo mesmo Worker não deve passar pelo HTMLRewriter; limite a transformação às rotas e aos tipos de conteúdo que você realmente verificou.
  • Executar a transformação duas vezes na mesma resposta (um retry ou fetch aninhado) — confirme que ela não acrescenta uma segunda tag.

Adicionando ou corrigindo alternates hreflang

O mesmo mecanismo, orientado por configuração. Você acrescenta um link[rel="alternate"] por localidade em head. Se seus alternates forem por localidade e relacionais, essa configuração pertence ao D1; se for uma consulta simples, KV basta. O ponto é que o HTMLRewriter os injeta da mesma maneira para cada solicitante — você não cria ramificações com base no user agent.

Injetando dados estruturados JSON-LD

new HTMLRewriter().on("head", {
  element(head) {
    head.append(
      `<script type="application/ld+json">${JSON.stringify(schema)}</script>`,
      { html: true }
    );
  },
});

Limites de CPU que pesam em escala

Uma afirmação de concorrente à qual eu faria objeção é “submilissegundo, sem restrições”. O teto real é o tempo de CPU: 10 ms no plano gratuito, 30 ms no pago (o tempo de parede esperando um fetch não conta — o tempo de CPU conta). Para reescritas típicas, você nunca perceberá. Para passagens pesadas de HTMLRewriter sobre páginas muito grandes, é uma restrição real a considerar no projeto, não alarmismo.

Redirecionamentos na borda: KV versus D1 versus Rules

Normalmente prefiro manter redirecionamentos na borda (no nível da CDN) em vez de no servidor — isso descarrega o trabalho da origem e é aplicado antes mesmo de a página ser gerada. Especificamente na Cloudflare, no meu guia da Ahrefs sobre redirecionamentos para SEO, expliquei que você tem várias opções: redirecionamentos individuais ou em massa, regras de redirecionamento, page rules ou Workers com pares chave-valor — ou um Worker que modifica headers para adicionar um redirecionamento.

Para uma tabela orientada por Worker, KV é o lugar natural: uma consulta rápida e eventualmente consistente por chave de URL.

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const target = await env.REDIRECTS.get(url.pathname);   // KV namespace
    if (target) return Response.redirect(target, 301);
    return fetch(request);
  },
};

Use D1 quando os redirecionamentos forem relacionais (por localidade, por segmento e consultados via SQL). E reconheça quando um Worker é exagero: para um conjunto pequeno e estático de redirecionamentos, os Bulk Redirects ou Redirect Rules da Cloudflare são mais simples e não exigem código. Não crie manualmente um Worker em KV para cinquenta redirecionamentos.

Escolha um responsável por uma determinada URL e não deixe um redirecionamento do Worker, um Bulk Redirect, uma Redirect Rule e um redirecionamento da origem serem aplicados ao mesmo caminho — são sistemas separados que podem ser acionados na mesma solicitação e, quando mais de um corresponde, você depura precedência em vez de um redirecionamento limpo. Antes de adicionar um redirecionamento em qualquer lugar, verifique se já existe um para aquele caminho nos outros sistemas e escolha a camada com base na complexidade da correspondência (1:1 simples versus baseada em padrões), na escala e em quem precisa observá-lo ou revertê-lo — o redirecionamento de um Worker vive no seu código e nos seus logs; um Bulk Redirect ou Rule vive no dashboard e é mais fácil de auditar ou reverter para quem não é desenvolvedor.

Cache: três coisas diferentes, um nome confuso

Esta é a seção que as páginas concorrentes ignoram e que gera a maior parte da confusão de “por que minha mudança não apareceu”. Três camadas separadas compartilham a palavra cache:

  • Workers Cache APIcaches.default e caches.open(). Este é um cache programável no escopo do Worker, que você lê e grava no código.
  • Cache de borda da Cloudflare — o cache da CDN que serve seus ativos. É distinto da Cache API.
  • Cache-Control da origem — os headers definidos pela origem (ou pelo Worker), que influenciam ambos os itens acima e o que o Googlebot faz.

Confunda-os e você jurará que uma mudança não foi implantada, quando na verdade ela está sendo servida por uma camada que você não limpou.

Quando uma mudança realmente não aparece, não adivinhe — diagnostique camada por camada:

  1. Chave de cache. Quais atributos da solicitação determinam se duas solicitações atingem a mesma entrada em cache (URL e, às vezes, headers ou cookies se a chave os incluir)? Uma reescrita que varia por algo fora da chave de cache pode servir a variante errada.
  2. Qual camada serviu a resposta. Verifique CF-Cache-Status (HIT/MISS/EXPIRED/DYNAMIC) para saber se o cache de borda respondeu ou se a solicitação chegou ao Worker.
  3. Localização/estado. O cache da Cloudflare é distribuído por datacenters — uma limpeza ou uma implantação nova não necessariamente invalida instantaneamente todos os locais de borda.
  4. TTL e a regra que o definiu. Confirme se uma regra de cache, um header Cache-Control da origem ou um header definido pelo próprio Worker controla o TTL.
  5. Invalidação. Você limpou a URL específica, limpou tudo ou esperou a expiração do TTL? Uma entrada da Cache API controlada pelo Worker (caches.default) precisa de seu próprio delete() explícito — limpar o cache da CDN não a altera.

O que o Googlebot faz com ETag / If-None-Match / 304

Se o seu Worker gera ou reescreve a resposta, ele controla os headers de cache — o que significa que a orientação de cache HTTP do Google de dezembro de 2024 é diretamente acionável para você. O Google aceita cache HTTP heurístico por meio de ETag/If-None-Match e Last-Modified/If-Modified-Since, recomenda fortemente ETag porque ele é menos propenso a erros e diz que, quando o ETag do rastreador coincide, seu servidor deve retornar um status 304 Not Modified sem corpo. Um Worker que gera a resposta pode implementar exatamente isso: calcular um ETag, compará-lo com If-None-Match e retornar imediatamente um 304 — economizando computação e fornecendo ao Googlebot um sinal rápido e armazenável em cache.

A troca de recrawl do max-age

O Google também recomenda considerar a configuração de Cache-Control: max-age para ajudar rastreadores a decidir quando rastrear novamente. A ressalva para um Worker que reescreve HTML: um max-age agressivo em uma página cujas tags injetadas pelo Worker acabaram de mudar pode atrasar o Googlebot de ver a atualização recém-publicada. Não coloque uma vida útil longa de cache em HTML reescrito e esqueça dele.

A fronteira do cloaking, aplicada aos Workers

A regra rígida, nos termos de Workers, é: execute a mesma lógica para todos os solicitantes. A política de spam do Google define cloaking como apresentar conteúdo diferente a usuários e mecanismos de busca para manipular rankings e destaca especificamente inserir texto ou palavras-chave apenas quando o solicitante é um mecanismo de busca.

Alguns esclarecimentos, porque as pessoas exageram na correção:

  • Inspecionar o User-Agent não é automaticamente cloaking. Registrar tráfego de bots ou servir uma resposta em cache mais rapidamente a qualquer cliente é aceitável. A linha é uma diferença de conteúdo por identidade do solicitante, feita para manipular rankings.
  • Testes A/B divididos por página em Workers são aceitáveis. Dividir usuários por URL e tratar todos os solicitantes da mesma forma é legítimo. Dividir por quem está solicitando — bot versus humano — não é.

Um exemplo prático do padrão seguro: o próprio gate de preview deste site é um Worker que retorna 404 para qualquer caminho /preview/, a menos que um cookie corresponda a um segredo. Ele retorna esse 404 para todos sem o cookie — incluindo o Googlebot. Essa é exatamente a forma segura: não esconde uma coisa dos bots e mostra outra aos usuários; aplica uma regra uniformemente.

E não dependa de uma etapa de pré-renderização exclusiva para bots, mesmo que você a construa corretamente em Workers. O Google chamou a renderização dinâmica de solução alternativa, e não solução de longo prazo; um Worker que pré-renderiza apenas para bots herda essa descontinuação.

Como um Worker pode bloquear ou deixar o Googlebot mais lento acidentalmente

Esta é a forma mais específica dos Workers de dar um tiro no próprio pé, e normalmente não está no código do Worker.

O Bot Fight Mode roda fora do Ruleset Engine

O Bot Fight Mode (e o Super Bot Fight Mode) pode gerar falsos positivos contra rastreadores legítimos, incluindo o Googlebot. A armadilha: o Bot Fight Mode é avaliado em um pipeline separado do WAF Ruleset Engine, então suas regras personalizadas comuns de “allow” ou “skip” não o substituem. Se o Bot Fight Mode estiver desafiando o Googlebot, você não corrige isso com uma regra de permissão — precisa alterar ou desativar o próprio modo. (Confirme a mecânica atual na documentação de Bot Fight Mode e Super Bot Fight Mode da Cloudflare antes de depender dela — os produtos de bots mudam.)

O padrão de regra personalizada para bots verificados

A Cloudflare expõe um campo cf.client.bot e um padrão de permissão para bots verificados para permitir rastreadores conhecidos e confiáveis nas regras personalizadas — útil para o lado do WAF, embora (como acima) não alcance o Bot Fight Mode.

A própria CDN é neutra ou positiva

Para deixar o mito claro: a Cloudflare como CDN não prejudica o SEO. O próprio trabalho de 2024 do Google, Crawling December, observa que o Google aumenta a taxa de rastreamento quando detecta uma CDN — mas que uma CDN também pode bloquear acidentalmente o Googlebot por meio de regras de WAF/bots e que um 503 é melhor que um intersticial de verificação de bot. O risco é um Worker ou configuração de bot mal configurado, não a infraestrutura.

Verificando o que o Googlebot realmente recebeu

Depois de qualquer implantação de Worker, confirme o que um rastreador realmente recebeu — não presuma:

  • GSC URL Inspection → Test Live URL. Busca a página como o Google e mostra o HTML renderizado, para que você confirme se a canonical/hreflang/JSON-LD injetada está realmente presente.
  • Verifique CF-Cache-Status junto com o HTML. HIT / MISS / EXPIRED informa se você está vendo uma resposta nova do Worker ou uma resposta em cache — a forma mais rápida de descobrir que “a mudança não apareceu” por causa da camada de cache.
  • Busque diretamente como Googlebot. Faça a solicitação com o user agent do Googlebot e compare — mas lembre-se de que corresponder à string não prova nada sobre a identidade; verifique o Googlebot real com DNS reverso + direto contra os intervalos publicados pelo Google (veja a aba Scripts).

Higiene de implantação específica dos Workers

Uma implantação bem-sucedida do wrangler deploy informa que o script foi enviado — não que o Googlebot está recebendo a saída renderizada correta. Trate cada mudança de Worker que afete SEO como uma versão com registro, não apenas como um push:

  • Defina o escopo das rotas. Não execute um Worker em /* por padrão. Combine-o com os caminhos necessários nos padrões de rota do wrangler.toml para que um bug não derrube o site inteiro.
  • Verifique os limites atuais antes de prometer escala. Limites de CPU, quantidade de subrequests e tamanho do script variam por plano e mudam com o tempo — confirme na página atual de limites da Cloudflare antes de projetar uma reescrita em torno de um teto específico, em vez de confiar em um número lembrado.
  • Registre metadados de versão para a publicação. O modelo de versões e implantações da Cloudflare acompanha versão do código-fonte, data de compatibilidade, bindings e rotas para cada implantação — anote qual versão está ativa em qual rota para que uma afirmação de que “o Worker faz X” possa ser verificada contra o que está realmente implantado, não contra o editor.
  • Faça versionamento e rollback com ambientes do Wrangler. Publique em um ambiente de staging, faça lançamento gradual por porcentagem e mantenha a capacidade de reverter instantaneamente para a versão anterior.
  • Use logs com escopo para monitorar o lançamento — considerando seus limites. Os Workers Logs e o tail de logs da Cloudflare podem ajudar a depurar um lançamento gradual, mas os logs são amostrados e mantidos por uma janela limitada — trate-os como evidência com escopo para as solicitações capturadas, não como registro completo de cada visita de rastreador.
  • Defina uma condição de parada e teste o rollback antes de precisar dele. Decida antecipadamente qual comportamento observado (taxa de erro, resposta errada em uma verificação pontual, queda da taxa de rastreamento) interrompe o lançamento e confirme que o caminho de rollback realmente funciona, em vez de presumir que funcionará.
  • Limpe o cache como parte da implantação. Como existem três camadas de cache, faça da limpeza/invalidação uma etapa explícita da publicação de uma reescrita, não uma reflexão tardia.

Uma observação sobre o Bing e uma questão para o futuro

O Bing também não tem orientação específica para Cloudflare/borda. Mas, como uma implantação de Worker é instantânea e os rastreamentos não são, o IndexNow é o complemento natural — dispare-o no momento em que uma tabela de redirecionamentos ou mudança de tag orientada por Worker for publicada para que o Bing (e outros mecanismos participantes) rastreiem novamente prontamente. E vale observar: a Cloudflare lançou a canonicalização imposta na borda como recurso de produto (“Redirects for AI Training”) — rastreadores de treinamento de IA verificados recebem um 301 para sua URL canonical com uma única opção. É um contraste útil com criar manualmente a lógica canonical no seu Worker e um lembrete de que “servir algo diferente a rastreadores e usuários” é um padrão sobre o qual a Microsoft demonstrou ceticismo publicamente nos demais recursos de rastreadores de IA da Cloudflare — uma boa verificação intuitiva para qualquer Worker condicional por bot.

Para o panorama mais amplo — comparação de plataformas, Snippets versus Workers e os ângulos de fila de desenvolvimento e governança — volte ao hub de Edge SEO.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.