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
Installs just this skill. Get the whole plugin for auto-invocation.
โก How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/netlify-edge-functions
๐๏ธ Context preview
The summary Claude sees to decide when to auto-load this skill.
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
๐ Stats
Stars27
Forks8
LanguageTypeScript
LicenseMIT
๐ฆ Ships with netlify-skills
</> SKILL.md
netlify-edge-functions.SKILL.md
---name: netlify-edge-functions
description: 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.
---# Netlify Edge Functions
Edge functions run on Netlify's globally distributed edge network (Deno runtime), providing low-latency responses close to users.
## Check the framework adapter first
For framework projects, check the framework reference (the **netlify-frameworks** skill) before hand-writing an edge function โ framework adapters emit their own edge middleware, so the behavior you need may already be generated. A custom edge function that duplicates adapter-generated middleware causes conflicts.
## Syntax
```typescript
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
```typescript
onError: "bypass", // "fail" (default), "bypass", or "/error-page"
cache: "manual", // Enable response caching
};
```
**Scope `path` narrowly โ `path: "/*"` intercepts every request, including static assets.** A `/*` match runs the edge function on every CSS, JS, image, and font request, not just your HTML pages โ adding latency to each asset and billing an edge invocation for it. Match only the routes you need (e.g. `path: "/"`, `path: "/app/*"`), or keep a broad path but exclude static assets with `excludedPath` (e.g. `excludedPath: ["/*.css", "/*.js", "/*.png", "/*.woff2"]`).
**Cache headers on an edge response do nothing without `cache: "manual"`.** Setting `Cache-Control` (or any cache header) on the `Response` an edge function returns has no effect unless the function also opts in with `config.cache = "manual"`. It's both or neither: without the flag the response is never cached, no matter what headers you set.
## Declaring edge functions: inline config vs netlify.toml
An edge function runs only if it is bound to a path. Bind it either with an inline `export const config = { path: ... }` in the function file (shown above), or with an `[[edge_functions]]` entry in `netlify.toml` that names the file:
```toml
[[edge_functions]]
path = "/admin/*"
function = "auth" # runs netlify/edge-functions/auth.ts
```
**A file in `netlify/edge-functions/` with no path binding still deploys, but silently never runs.** There is no build error and no warning โ nothing routes a request to it, so it is never invoked. If an edge function "isn't doing anything," first confirm it declares a `path` inline or has a matching `[[edge_functions]]` entry.
### Chaining multiple edge functions on one path
When several edge functions match the same path, they run as a chain in this order:
1. Functions declared in `netlify.toml` run first, **in the order they appear** in the file (top to bottom).
2. Functions declared inline (via `export const config`) run next, **in alphabetical order by filename**.
3. Functions configured for caching (`cache: "manual"`) always run after non-caching ones.
To guarantee a specific order (e.g. an auth gate that must run before a personalization rewrite), declare the functions in `netlify.toml` in the order you want โ don't depend on inline config, whose order is alphabetical by filename and easy to get wrong. Declaring the same function both inline and in `netlify.toml` merges them into an inline declaration (inline config wins), which forfeits the deterministic `netlify.toml` ordering.
## Edge functions run before redirects
In Netlify's request chain, edge functions execute **before** redirect and rewrite rules (`[[redirects]]`, `_redirects`). Two consequences bite often:
- An edge function is matched against the **original** requested URL, not a redirect/rewrite destination. Scope its `path` to the URL the client actually requests โ an edge function declared on the *target* of a rewrite will not fire for requests that only reach that target via the rewrite.
- If an edge function returns a `Response`, the request chain stops there and redirect rules for that path **never run**. Return `context.next()` (or `undefined`) if you want redirects to still apply.
## Middleware Pattern
Use `context.next()` to invoke the next handler in the chain and optionally modify the response: