CtrlK
BlogDocsLog inGet started
Tessl Logo

netlify-edge-functions

Guide for writing Netlify Edge Functions. Use when building middleware, geolocation-based logic, request/response manipulation, authentication checks, A/B testing, or any low-latency edge compute. Covers Deno runtime, context.next() middleware pattern, geolocation, and when to choose edge vs serverless.

73

Quality

89%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

SKILL.md
Quality
Evals
Security

Netlify Edge Functions

Edge functions run on Netlify's globally distributed edge network (Deno runtime), providing low-latency responses close to users.

Syntax

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.

Config Object

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

Middleware Pattern

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

Geolocation and IP

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

Environment Variables

Use Netlify.env (not process.env or Deno.env):

const secret = Netlify.env.get("API_SECRET");

Module Support

  • Node.js builtins: import { randomBytes } from "node:crypto";
  • npm packages: Install via npm and import by name
  • Deno modules: URL imports (e.g., 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"

When to Use Edge vs Serverless

Use Edge Functions forUse Serverless Functions for
Low-latency responsesLong-running operations (up to 15 min)
Request/response manipulationComplex Node.js dependencies
Geolocation-based logicDatabase-heavy operations
Auth checks and redirectsBackground/scheduled tasks
A/B testing, personalizationTasks needing > 512 MB memory

Limits

ResourceLimit
CPU time50 ms per request
Memory512 MB per deployed set
Response header timeout40 seconds
Code size20 MB compressed
Repository
netlify/context-and-tools
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.