From netlify-skills
Guides Netlify Edge Functions for middleware with context.next(), geolocation, request/response manipulation, auth checks, A/B testing, and low-latency compute using Deno runtime.
npx claudepluginhub netlify/context-and-tools --plugin netlify-skillsThis skill uses the workspace's default tool permissions.
Edge functions run on Netlify's globally distributed edge network (Deno runtime), providing low-latency responses close to users.
Builds and deploys Vercel Edge Functions for low-latency APIs, geolocation routing, A/B testing, edge auth, and middleware using Web APIs.
Guides writing Netlify serverless functions with modern TypeScript syntax, path/method routing, background processing, scheduled tasks, and streaming for API endpoints and server-side logic.
Guides designing edge computing architectures, serverless at edge, and distributed compute strategies. Covers edge functions, Cloudflare Workers, Lambda@Edge, compute placement, and edge-native patterns.
Share bugs, ideas, or general feedback.
Edge functions run on Netlify's globally distributed edge network (Deno runtime), providing low-latency responses close to users.
import type { Config, Context } from "@netlify/edge-functions";
export default async (req: Request, context: Context) => {
return new Response("Hello from the edge!");
};
export const config: Config = {
path: "/hello",
};
Place files in netlify/edge-functions/. Uses .ts, .js, .tsx, or .jsx extensions.
export const config: Config = {
path: "/api/*", // URLPattern path(s)
excludedPath: "/api/public/*", // Exclusions
method: ["GET", "POST"], // HTTP methods
onError: "bypass", // "fail" (default), "bypass", or "/error-page"
cache: "manual", // Enable response caching
};
Use context.next() to invoke the next handler in the chain and optionally modify the response:
export default async (req: Request, context: Context) => {
// Before: modify request or short-circuit
if (!isAuthenticated(req)) {
return new Response("Unauthorized", { status: 401 });
}
// Continue to origin/next function
const response = await context.next();
// After: modify response
response.headers.set("x-custom-header", "value");
return response;
};
Return undefined to pass through without modification:
export default async (req: Request, context: Context) => {
if (!shouldHandle(req)) return; // continues to next handler
return new Response("Handled");
};
export default async (req: Request, context: Context) => {
const { city, country, subdivision, timezone } = context.geo;
const ip = context.ip;
if (country?.code === "DE") {
return Response.redirect(new URL("/de", req.url));
}
};
Local dev with mocked geo: netlify dev --geo=mock --country=US
Use Netlify.env (not process.env or Deno.env):
const secret = Netlify.env.get("API_SECRET");
import { randomBytes } from "node:crypto";import X from "https://esm.sh/package")For URL imports, use an import map:
// import_map.json
{ "imports": { "html-rewriter": "https://ghuc.cc/worker-tools/html-rewriter/index.ts" } }
# netlify.toml
[functions]
deno_import_map = "./import_map.json"
| Use Edge Functions for | Use Serverless Functions for |
|---|---|
| Low-latency responses | Long-running operations (up to 15 min) |
| Request/response manipulation | Complex Node.js dependencies |
| Geolocation-based logic | Database-heavy operations |
| Auth checks and redirects | Background/scheduled tasks |
| A/B testing, personalization | Tasks needing > 512 MB memory |
| Resource | Limit |
|---|---|
| CPU time | 50 ms per request |
| Memory | 512 MB per deployed set |
| Response header timeout | 40 seconds |
| Code size | 20 MB compressed |