Advanced (Updated: 6/2/2026)

Leveraging Edge Computing with Claude Code

Design Edge runtime work with Claude Code: Workers, geo branching, cache keys, pitfalls, and verification commands.

Leveraging Edge Computing with Claude Code

Edge computing is the practice of doing small decisions close to the user. Instead of sending every request to one central server, you can decide redirects, cache short-lived content, assign A/B buckets, or block obvious unauthorized traffic at a nearby edge location.

That does not make the edge a magic performance button. An Edge runtime is not the same as a normal Node.js server. APIs, execution time, packages, request metadata, and cache behavior all have constraints. If you ask Claude Code only to “make this edge-ready”, it may import Node-only APIs, build the wrong cache key, or use country data for decisions that should require authenticated server data.

This guide uses official documentation checked on June 2, 2026 and turns it into a practical Claude Code workflow. Keep these references open: Cloudflare Workers, Workers Request API, Workers Cache API, Vercel Edge Runtime, Deno Deploy runtime, and Claude Code overview. For deeper provider-specific guides, continue with Cloudflare Workers with Claude Code and Claude Code and Vercel Edge Functions.

Decide What Belongs at the Edge

The first design step is deciding what should run at the edge. A good rule is simple: if the decision can be made from the URL, headers, cookies, or a small request body, it may be a good edge task. If the work needs deep database reads, long LLM calls, image processing, billing settlement, or a background workflow, keep it in a regular API or queue.

Use caseWhy it fits the edgeKeep this elsewhere
Country or language routingA country code or language header can choose an entry path quicklyTax calculation, invoices, inventory
Short cacheRepeated public responses can be served near the userDatabase updates and regeneration jobs
A/B assignmentA cookie can choose a bucket before the page rendersStatistical analysis and revenue decisions
Light auth gatePreview and admin paths can be blocked earlySession creation and permission audits
Webhook entry checkA small signature check can reject bad requestsPayment processing, emails, retries

Put this table in the prompt you give Claude Code. The output becomes easier to review because “edge work” and “origin work” are separated before code is generated.

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"]

The Prompt to Give Claude Code

For edge work, the prompt should describe constraints, not only the desired speed. Claude Code is good at producing code quickly, but cache keys, region branches, secrets, and verification commands are easy to miss unless you ask for them explicitly.

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

Explain a few terms in the task brief. A runtime is the environment where code runs. A cache key is the name used to find a cached response. A colo is Cloudflare’s data center identifier. These small definitions help Claude Code write beginner-friendly comments and review notes.

A Copy-Paste Cloudflare Workers Example

The following Worker is intentionally small. /api/edge-content reads a country from Cloudflare request metadata or from a local test header, maps it to a locale, and stores the response in the Cache API for 60 seconds. The local header fallback means you can test the branch with curl before deploying.

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;
}

The important detail is the cache key: it contains locale. Without that, a Japanese CTA could be cached and returned to an English visitor. At the same time, the key removes the query string so tracking parameters such as utm_source do not split the cache into hundreds of useless entries.

Extend the Pattern to Vercel and Deno

Vercel Edge Middleware is useful before a page is rendered. It can set headers, persist an A/B bucket, and redirect a country-specific entry path. Keep the Edge Runtime constraints in mind and avoid packages that require Node-only APIs.

// 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";
}

For Deno Deploy, keep the same Web API shape and avoid copying Cloudflare-only fields such as request.cf. Provider headers and environment variables differ, so make them explicit in the 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",
  });
});

Verification Commands

For edge code, verify types, local HTTP behavior, geo branching, cache headers, and deploy readiness. Ask Claude Code to leave this evidence in its handoff instead of saying only that the code was implemented.

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

Run these curl checks in another terminal.

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

The expected behavior is direct: the first matching request returns X-Edge-Cache: MISS; the next request for the same locale and path returns HIT. Japan maps to ja, the United States maps to en, and the tracking query does not create a separate cache entry.

Common Pitfalls

The first pitfall is putting too much at the edge. Long LLM calls, ORM-heavy database work, PDF generation, image conversion, and complex billing flows usually belong in an origin API or background queue. Keep the edge as an entry gate, not the whole backend.

The second pitfall is using a cache key that is either too broad or too narrow. If locale, auth state, price display, or experiment bucket changes the response, it must be part of the key. If noisy fields such as utm_* are part of the key, the cache will rarely hit.

The third pitfall is over-trusting geography. Cloudflare request.cf.country and Vercel x-vercel-ip-country are useful for experience defaults, but they are not proof for tax, age, permission, or billing decisions. VPNs, company proxies, and CDN routing can change the observed country.

The fourth pitfall is giving Claude Code only a provider name. “Build this with Workers” does not say whether to use the Cache API, KV, D1, Vercel compatibility, or origin fallback. Use the decision table above, then compare with Claude Code serverless functions and Claude Code performance optimization when choosing the boundary.

Revenue Path and Next Steps

Edge runtime can improve revenue paths on a multilingual content site. You can show the right free PDF copy, route users to the closest language, normalize tracking parameters before caching, and keep template CTAs fast without changing the core application.

For reusable implementation material, see ClaudeCodeLab products. For team adoption, prompt templates, review rules, and the boundary between Edge and Node, see Claude Code training and consulting. If you want the quick workflow first, start with the free cheat sheet.

What I Actually Tested

For this update, Masa tested the Workers sample locally by switching between CF-IPCountry: JP and CF-IPCountry: US, checking locale, X-Edge-Cache, and the cache key that removes tracking parameters. The useful finding was that local verification is more reliable when the test headers are read before request.cf.country; otherwise the country branch can look sticky during repeated checks. The cache key also uses /__edge-cache/${locale}${pathname} so regional content does not mix. When you brief Claude Code, ask it to review header priority, geo branching, and cache keys together.

Summary

Edge computing is not a migration of everything to the edge. It is a design choice: small request decisions run close to the user, while heavy work and final decisions remain in the normal API. Give Claude Code the runtime limits, cache-key rules, geo branching, and verification commands up front. The result is not only faster; it is much easier to review.

#Claude Code #edge computing #Cloudflare Workers #Vercel #performance
Free

Free PDF: Claude Code Cheatsheet

Enter your email and download the one-page Claude Code cheatsheet for commands, review habits, and safe workflows.

We handle your data with care and never send spam.

Level up your Claude Code workflow

Start with the free PDF, use Gumroad guides when you need repeatable workflows, and book consultation when rollout or revenue paths need human judgment.

Masa

About the Author

Masa

Engineer focused on practical Claude Code workflows. Runs claudecode-lab.com, a 10-language technical media site.