Advanced (Atualizado: 02/06/2026)

Edge Computing com Claude Code: Workers, cache e rotas por região

Projete Edge runtime com Claude Code: Workers, região, cache keys, riscos e comandos de verificação.

Edge Computing com Claude Code: Workers, cache e rotas por região

Edge computing é tomar pequenas decisões perto do usuário. Não significa mover todo o backend para a borda da rede. Significa resolver redirecionamentos, cache curto, distribuição de A/B test ou bloqueios simples antes que a requisição chegue à aplicação principal.

Por isso, Edge runtime não é um botão mágico de performance. Ele não é um servidor Node.js comum. APIs disponíveis, tempo de execução, pacotes, metadados da requisição e comportamento de cache têm limites. Se você pedir ao Claude Code apenas “deixe isso pronto para edge”, ele pode importar APIs exclusivas de Node, montar uma cache key errada ou usar país como prova de cobrança e permissão.

Este guia usa documentação oficial verificada em 2 de junho de 2026. Mantenha abertos Cloudflare Workers, Workers Request API, Workers Cache API, Vercel Edge Runtime, Deno Deploy runtime e Claude Code overview. Para aprofundar por plataforma, veja também Cloudflare Workers com Claude Code e Vercel Edge Functions com Claude Code.

Decida o que pertence ao Edge

O primeiro passo é separar controle de entrada de lógica de negócio. Se a decisão pode ser tomada com URL, headers, cookies ou um corpo pequeno, ela pode caber no Edge. Se exige leituras profundas de banco, chamadas longas a LLM, processamento de imagem, PDF, fechamento de pagamento ou tarefa em background, deixe em uma API comum ou fila.

Caso de usoPor que combina com EdgeDeixe fora do Edge
Rota por país ou idiomaCódigo de país ou header de idioma escolhe a entrada rápidoImpostos, faturas, estoque
Cache curtoResposta pública pode ser servida perto do usuárioAtualizações de DB e regeneração
Atribuição A/BCookie define a variante antes do renderAnálise estatística e decisão de receita
Autenticação levePreview e admin podem ser bloqueados cedoCriação de sessão e auditoria
Entrada de webhookUma assinatura pequena rejeita requisições ruinsPagamento, e-mail, retentativas

Inclua essa tabela no prompt para Claude Code. O resultado fica mais fácil de revisar porque o trabalho do Edge e o trabalho da origem já estão separados.

flowchart LR
  User["User request"] --> Edge["Edge runtime"]
  Edge --> Geo["Country / language branch"]
  Edge --> Cache["Short cache"]
  Edge --> Gate["Light auth gate"]
  Edge --> Origin["Origin API / database"]
  Origin --> Queue["Queue or background work"]

Prompt para o Claude Code

Em código Edge, o prompt deve explicar restrições, não apenas pedir velocidade. Claude Code gera código rápido, mas cache keys, ramificações regionais, secrets e comandos de verificação costumam escapar quando não aparecem como requisitos.

Implement a small Cloudflare Workers + TypeScript Edge runtime API.

Files:
- wrangler.toml
- src/index.ts

Requirements:
- GET /health returns JSON
- GET /api/edge-content returns locale and CTA copy based on country
- Use request.cf.country when Cloudflare provides it
- Also support a CF-IPCountry header for local curl verification
- Cache each locale separately for 60 seconds with the Cache API
- Return cache hit/miss through X-Edge-Cache
- Use Web APIs such as Request, Response, URL, and crypto; do not use Node-only APIs
- Include at least three curl or build commands that verify the behavior

Do not:
- Use pseudocode
- Hard-code API tokens or secrets
- Treat country code as proof for billing, permissions, or legal decisions

Explique alguns termos no próprio pedido. runtime é o ambiente onde o código roda. cache key é o nome usado para encontrar uma resposta em cache. colo é o identificador de data center da Cloudflare. Essas definições ajudam Claude Code a produzir comentários e notas de entrega mais claras.

Exemplo copiável de Cloudflare Workers

O Worker abaixo é pequeno de propósito. /api/edge-content lê o país a partir dos metadados da Cloudflare ou de um header local de teste, transforma isso em locale e salva a resposta por 60 segundos com Cache API. O header CF-IPCountry permite testar o desvio regional com curl antes do deploy.

name = "claude-edge-router"
main = "src/index.ts"
compatibility_date = "2026-06-02"

[vars]
DEFAULT_LOCALE = "en"
// src/index.ts
export interface Env {
  DEFAULT_LOCALE: string;
}

type Locale = "ja" | "en" | "zh" | "ko" | "es" | "fr" | "de" | "pt" | "hi" | "id";

type CfRequest = Request & {
  cf?: {
    country?: string;
    colo?: string;
    city?: string;
  };
};

const SUPPORTED_LOCALES = new Set<Locale>([
  "ja",
  "en",
  "zh",
  "ko",
  "es",
  "fr",
  "de",
  "pt",
  "hi",
  "id",
]);

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/health") {
      return json({ ok: true, runtime: "cloudflare-workers" });
    }

    if (url.pathname === "/api/edge-content") {
      return handleEdgeContent(request, env, ctx);
    }

    return json({ error: "not_found" }, 404);
  },
} satisfies ExportedHandler<Env>;

async function handleEdgeContent(
  request: Request,
  env: Env,
  ctx: ExecutionContext
): Promise<Response> {
  const url = new URL(request.url);
  const country = getCountry(request);
  const locale = localeFromCountry(country, env.DEFAULT_LOCALE);
  const cacheKey = buildCacheKey(request, locale);
  const cached = await caches.default.match(cacheKey);

  if (cached) {
    return withHeaders(cached, {
      "X-Edge-Cache": "HIT",
      "X-Edge-Locale": locale,
    });
  }

  const body = {
    locale,
    country,
    colo: getColo(request),
    path: url.pathname,
    cta: localizedCta(locale),
    generatedAt: new Date().toISOString(),
  };

  const response = json(body, 200, {
    "Cache-Control": "public, max-age=0, s-maxage=60, stale-while-revalidate=300",
    "X-Edge-Cache": "MISS",
    "X-Edge-Locale": locale,
  });

  ctx.waitUntil(caches.default.put(cacheKey, response.clone()));
  return response;
}

function buildCacheKey(request: Request, locale: Locale): Request {
  const url = new URL(request.url);
  url.search = "";
  url.pathname = `/__edge-cache/${locale}${url.pathname}`;
  return new Request(url.toString(), { method: "GET" });
}

function getCountry(request: Request): string {
  const cf = (request as CfRequest).cf;
  return (
    request.headers.get("CF-IPCountry") ||
    request.headers.get("x-country") ||
    cf?.country ||
    "US"
  ).toUpperCase();
}

function getColo(request: Request): string {
  return (request as CfRequest).cf?.colo || "local";
}

function localeFromCountry(country: string, fallback: string): Locale {
  const normalizedFallback = SUPPORTED_LOCALES.has(fallback as Locale)
    ? (fallback as Locale)
    : "en";

  switch (country) {
    case "JP":
      return "ja";
    case "CN":
    case "TW":
    case "HK":
      return "zh";
    case "KR":
      return "ko";
    case "ES":
    case "MX":
    case "AR":
      return "es";
    case "FR":
      return "fr";
    case "DE":
      return "de";
    case "BR":
    case "PT":
      return "pt";
    case "IN":
      return "hi";
    case "ID":
      return "id";
    default:
      return normalizedFallback;
  }
}

function localizedCta(locale: Locale): string {
  const messages: Record<Locale, string> = {
    ja: "Claude Code教材を見る",
    en: "Explore Claude Code templates",
    zh: "查看 Claude Code 教材",
    ko: "Claude Code 템플릿 보기",
    es: "Ver plantillas de Claude Code",
    fr: "Voir les modèles Claude Code",
    de: "Claude Code Vorlagen ansehen",
    pt: "Ver modelos de Claude Code",
    hi: "Claude Code टेम्पलेट देखें",
    id: "Lihat template Claude Code",
  };
  return messages[locale];
}

function json(data: unknown, status = 200, headers: HeadersInit = {}): Response {
  return new Response(JSON.stringify(data, null, 2), {
    status,
    headers: {
      "Content-Type": "application/json; charset=utf-8",
      "X-Content-Type-Options": "nosniff",
      ...headers,
    },
  });
}

function withHeaders(response: Response, headers: Record<string, string>): Response {
  const next = new Response(response.body, response);
  for (const [key, value] of Object.entries(headers)) {
    next.headers.set(key, value);
  }
  return next;
}

O detalhe importante é a cache key: ela contém locale. Sem isso, uma CTA japonesa poderia ser entregue a um visitante em português ou inglês. A query também é removida para que parâmetros como utm_source não quebrem a cache em centenas de entradas inúteis.

Levar o padrão para Vercel e Deno

Vercel Edge Middleware é útil antes do render da página. Ele pode definir headers, persistir um bucket A/B e redirecionar uma rota regional. Respeite as restrições do Edge Runtime e evite pacotes que dependam de APIs exclusivas de Node.

// middleware.ts
import { NextRequest, NextResponse } from "next/server";

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};

export function middleware(request: NextRequest) {
  const country = request.headers.get("x-vercel-ip-country") || "US";
  const bucket = request.cookies.get("edge_bucket")?.value || chooseBucket();
  const response = NextResponse.next();

  response.headers.set("x-edge-country", country);
  response.headers.set("x-edge-bucket", bucket);
  response.cookies.set("edge_bucket", bucket, {
    maxAge: 60 * 60 * 24 * 30,
    sameSite: "lax",
    secure: true,
  });

  if (country === "JP" && request.nextUrl.pathname === "/pricing") {
    return NextResponse.redirect(new URL("/jp/pricing", request.url));
  }

  return response;
}

function chooseBucket(): "a" | "b" {
  const bytes = new Uint8Array(1);
  crypto.getRandomValues(bytes);
  return bytes[0] < 128 ? "a" : "b";
}

No Deno Deploy, mantenha o formato com Request e Response, mas não copie campos específicos da Cloudflare como request.cf. Headers e variáveis de ambiente mudam por provedor, então precisam aparecer no prompt.

// main.ts
Deno.serve((request: Request) => {
  const url = new URL(request.url);
  const country = request.headers.get("x-country") || "US";

  if (url.pathname !== "/api/edge-content") {
    return Response.json({ error: "not_found" }, { status: 404 });
  }

  return Response.json({
    runtime: "deno-deploy",
    country,
    message: country === "JP" ? "Japan entry" : "Default edge entry",
  });
});

Comandos de verificação

Código Edge deve ser verificado em tipos, HTTP local, desvio regional, headers de cache e prontidão de deploy. Peça ao Claude Code para deixar essa evidência na entrega.

npm create cloudflare@latest claude-edge-router -- --type=hello-world
cd claude-edge-router
npm install -D typescript wrangler
npx wrangler types
npx tsc --noEmit
npx wrangler dev

Em outro terminal, execute curl.

curl -i http://127.0.0.1:8787/health
curl -i -H "CF-IPCountry: JP" http://127.0.0.1:8787/api/edge-content
curl -i -H "CF-IPCountry: US" http://127.0.0.1:8787/api/edge-content
curl -i -H "CF-IPCountry: JP" "http://127.0.0.1:8787/api/edge-content?utm_source=test"
npx wrangler deploy --dry-run

O comportamento esperado é simples: a primeira requisição para locale e path retorna X-Edge-Cache: MISS; a próxima retorna HIT. JP vira ja, US vira en, e a query de tracking não cria uma entrada separada.

Armadilhas comuns

A primeira armadilha é colocar trabalho demais no Edge. Chamadas longas a LLMs, ORM pesado, PDF, imagem e cobrança complexa costumam pertencer a uma API de origem ou fila. Edge deve ser a porta de entrada, não o backend inteiro.

A segunda é uma cache key ampla ou estreita demais. Se locale, sessão, preço ou bucket experimental mudam a resposta, precisam estar na chave. Se ruído como utm_* ou timestamp entra na chave, a cache quase nunca acerta.

A terceira é confiar demais na geografia. request.cf.country e x-vercel-ip-country são úteis para defaults de experiência, mas não provam imposto, idade, permissão ou cobrança. VPN, proxy corporativo e rota de CDN podem mudar o país observado.

A quarta é dar ao Claude Code apenas o nome do provedor. “Faça com Workers” não diz se você quer Cache API, KV, D1, compatibilidade com Vercel ou fallback para origem. Para decidir a fronteira, compare com funções serverless com Claude Code e otimização de performance.

Caminho de receita e próximos passos

Em um site multilíngue de conteúdo, Edge runtime também melhora o caminho de receita. Você pode localizar o texto do PDF gratuito, enviar o leitor ao idioma certo, normalizar parâmetros de anúncio antes do cache e manter CTAs de templates rápidas.

Para materiais reutilizáveis, veja os produtos ClaudeCodeLab. Para equipes que querem padronizar prompts, regras de revisão e a fronteira entre Edge e Node, veja treinamento e consultoria Claude Code. Para começar com um fluxo curto, use a folha gratuita.

Resultado do teste real

Nesta atualização, Masa testou o Worker local alternando CF-IPCountry: JP e CF-IPCountry: US, verificando locale, X-Edge-Cache e a cache key sem parâmetros de tracking. O achado útil foi que, em local, os headers de teste devem ser lidos antes de request.cf.country; caso contrário, a ramificação por país pode parecer presa em checagens repetidas. A chave também usa /__edge-cache/${locale}${pathname} para não misturar conteúdo regional. Ao pedir isso ao Claude Code, peça revisão conjunta de prioridade de headers, ramificação regional e cache key.

Resumo

Edge computing não é mover tudo para a borda. É colocar pequenas decisões de requisição perto do usuário e manter trabalho pesado e decisões finais na API normal. Dê ao Claude Code limites do runtime, regras de cache key, ramificações regionais e comandos de verificação desde o início. O resultado será mais rápido e muito mais fácil de revisar.

#Claude Code #edge computing #Cloudflare Workers #Vercel #performance
Grátis

PDF grátis: cheatsheet do Claude Code

Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.

Cuidamos dos seus dados e não enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.