Quando um time adota Cloudflare Workers, o primeiro deploy é trivial: wrangler deploy, pronto, o script está no ar. Quando outro time adota Pages, o primeiro deploy também é trivial: conecta o repositório GitHub, configura o comando de build, pronto. O problema aparece quando os dois coexistem na mesma zona, quando você precisa de preview por branch, ou quando alguém precisa auditar o que está rodando em produção sem acessar o dashboard.
Como Workers faz deploy
O artefato central de um projeto Workers é o wrangler.toml. Nele ficam as rotas, os bindings, as variáveis de ambiente, os limites de compatibilidade e os environments. Um deployment típico produção/staging fica assim no mesmo arquivo:
name = "minha-api" main = "src/index.ts" compatibility_date = "2024-09-23" [[routes]] pattern = "api.exemplo.com/*" zone_name = "exemplo.com" [env.staging] name = "minha-api-staging" [[env.staging.routes]] pattern = "api-staging.exemplo.com/*" zone_name = "exemplo.com"
Isso é configuração versionada em código, revisável em pull request, rastreável no histórico do Git. Qualquer mudança de rota ou binding passa pelo mesmo processo de revisão do código.
O wrangler deploy --env staging faz deploy do script como um Worker separado (minha-api-staging), com suas próprias rotas e bindings. Environments em Workers são Workers distintos — não variantes do mesmo deploy.
Como Pages faz deploy
Pages funciona por git push. Você conecta um repositório, define o comando de build e o diretório de saída no dashboard, e cada push para a branch principal dispara um pipeline: clone, install, build, upload dos assets para o CDN. O pipeline roda em até 500 builds/mês no plano gratuito e 5.000/mês no plano pago ($20/mês).
A grande diferença operacional: cada push para qualquer branch que não seja a principal gera um preview deployment automático com URL única no formato hash-branch.seuprojet.pages.dev. Você abre um pull request, a Cloudflare comenta no PR com a URL do preview. A equipe de produto testa na URL antes de aprovar o merge. Workers não tem equivalente nativo para isso.
A limitação simétrica: as configurações de build do Pages — comando de build, variáveis de ambiente, versão do Node — ficam no dashboard, não em arquivo de código. Até hoje não há suporte completo a wrangler.toml para Pages. Isso significa que mudanças de configuração de build não passam por pull request e não ficam no histórico do Git. Para times que exigem audit trail completo de infraestrutura, isso é um atrito real.
Roteamento e a armadilha da colisão de rotas
Workers usa route patterns vinculados a uma zone. O pattern api.exemplo.com/v1/* captura todas as requisições para esse path e as entrega para o script correspondente. Se dois Workers diferentes tentam registrar o mesmo pattern na mesma zone, o segundo deploy falha com erro de conflito.
Pages usa um subdomínio dedicado (*.pages.dev) ou um domínio customizado vinculado ao projeto. Quando você usa domínio customizado em Pages, a Cloudflare cria um Worker interno que serve os assets e roteia para as Functions. Esse Worker interno ocupa as rotas do domínio.
O problema concreto: você tem um projeto Pages em app.exemplo.com e quer adicionar um Worker separado para processar webhooks em app.exemplo.com/webhooks. Não dá. As rotas do Pages já capturam app.exemplo.com/*. A solução é mover o handler de webhooks para uma Pages Function em /functions/webhooks.ts, ou usar um subdomínio separado (webhooks.exemplo.com) com um Worker independente.
O precedência de roteamento dentro de Pages segue uma ordem fixa: _redirects é processado primeiro, depois _headers, depois as Functions em /functions, e por último os assets estáticos. Isso quer dizer que uma Function em /functions/blog/[slug].ts tem prioridade sobre um arquivo estático em /blog/qualquer-coisa.html — o que pode ser surpreendente se você gerou páginas estáticas com o mesmo path.
Environments de Pages e o que falta
Pages tem o conceito de environments de produção e preview. Produção é a branch principal; qualquer outra branch gera um preview. Você pode configurar variáveis de ambiente separadas por environment no dashboard.
O que Pages não tem: múltiplos environments nomeados com configurações distintas de build. Workers permite wrangler deploy --env staging com um conjunto completamente diferente de bindings e variáveis. Em Pages, se você quer um ambiente de staging com um banco D1 diferente, você cria um projeto Pages separado e gerencia a sincronia entre os dois manualmente.
Para times que trabalham com staging rigoroso — banco de dados separado, keys de API de sandbox, feature flags distintos — essa limitação é significativa e geralmente empurra esses workloads para Workers.
Como o wrangler.toml vai (parcialmente) para Pages
A Cloudflare anunciou suporte experimental a wrangler.toml para configurar bindings de Pages Functions — KV namespaces, D1 databases, variáveis de ambiente. Isso resolve parte do problema de audit trail: os bindings ficam no código. Mas o pipeline de build (comando, diretório de saída, versão do Node) ainda fica no dashboard.
O estado atual é parcial. Quem precisa de configuração 100% em código hoje usa Workers com assets servidos via R2 + Cache API, abrindo mão do CDN gratuito de Pages. Esse é um trade-off real que vale calcular antes de tomar a decisão.
O que avaliar antes de decidir
O modelo de deploy do Pages oferece dois ativos concretos: pipeline de build integrado (sem CI externo para montar) e preview deployments automáticos por branch. Para times com designers e produto revisando features antes do merge, o preview por branch acelera o ciclo de revisão de forma mensurável.
Workers oferece configuração auditável em código desde o primeiro dia, environments nomeados com bindings distintos, e suporte a triggers não-HTTP (cron, filas, e-mail) que Pages não tem. Para APIs ou serviços sem componente visual que precisam de staging rigoroso, Workers estruturado com wrangler.toml bem organizado é operacionalmente mais limpo.
A colisão de rotas entre projetos na mesma zone é o gotcha mais comum de times que começam com Pages e depois tentam adicionar Workers isolados. O mapeamento mental correto: um domínio customizado em Pages é como um Workers que ocupa o wildcard daquele domínio. Qualquer outra coisa que você queira naquele domínio precisa morar dentro do projeto Pages.
Leia também
- Cloudflare Workers vs Pages: a diferença que importa antes de você escolher
- Migrar de Pages para Workers: quando faz sentido e o custo real da mudança
- O que só Workers faz, o que só Pages faz e onde os dois se encontram
- Pages Functions: quando usar em vez de Workers puros
- DNS proxied vs DNS only: o que muda e quando cada modo faz sentido
- O modelo de programação dos Durable Objects: o que é diferente de tudo que você já usou