diff --git a/README.md b/README.md index f446fc2..1a20aa7 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,14 @@ -![Netlify examples](https://user-images.githubusercontent.com/5865/159468750-df1c2783-39b2-40da-9c0f-971f72a7ea3f.png) +![Netlify examples](https://github.com/netlify/edge-functions-examples/assets/7912948/d34a626d-1c65-492d-bb14-85f50d9b72cb) -# [Netlify Edge Functions](https://www.netlify.com/products/?utm_campaign=devex&utm_source=edge-functions-examples&utm_medium=github&utm_content=Edge%20Functions%20Product%20Page#netlify-edge-functions) Examples - -Explore these examples here: https://edge-functions-examples.netlify.app/ - -## Responses - -- [Hello, world](/pages/hello) -- [Return JSON](/pages/json) -- [Return an image](/pages/image) - -## Rewrites and proxies - -- [Rewrite responses from another URL](/pages/rewrite) -- [Proxy requests to another source](/pages/proxy-requests) - -## HTTP Headers - -- [Set custom HTTP request headers](/pages/set-request-header) -- [Set custom HTTP response headers](/pages/set-response-header) - -## Transforming responses -- [Text transformation](/pages/transform) -- [Content includes](/pages/include) - -## Geolocation - -- [Determine a user's location](/pages/geolocation) -- [Block content according to country](/pages/country-block) -- [Serve localized content](/pages/localized-content) - -## Cookies - -- [Set cookies](/pages/cookies-set) -- [Read cookies](/pages/cookies-read) -- [Delete cookies](/pages/cookies-delete) -- [Set up an A/B test using cookies](/pages/abtest) - -## Streams -- [Long-running edge functions](/pages/long-running) -- [Server-sent events](/pages/server-sent-events) - -## WebAssembly -- [Edge WebAssembly](/pages/wasm) - -## Environment and debugging +# [Netlify Edge Functions](https://www.netlify.com/products/?utm_campaign=devex&utm_source=edge-functions-examples&utm_medium=github&utm_content=Edge%20Functions%20Product%20Page#netlify-edge-functions) Examples -- [Write to the logs](/pages/log) -- [Use environment variables](/pages/environment) +Try these examples here: https://edge-functions-examples.netlify.app/ --- -## Deploy this site to Netlify +## This code has a new home -Click this button to deploy this site automatically to your Netlify account. +This repo has been migrated into the [Netlify Examples monorepo](https://github.com/netlify/examples/tree/main/examples/edge-functions ). -[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/netlify/edge-functions-examples&utm_campaign=devex&utm_source=edge-functions-examples&utm_medium=web&utm_content=Deploy%20Edge%20Functions%20Examples%20to%20Netlify) +Explore the code for these examples, along with many others here: https://github.com/netlify/examples/ diff --git a/components/layout.js b/components/layout.js index 6ba5d3a..152d7b1 100644 --- a/components/layout.js +++ b/components/layout.js @@ -7,7 +7,7 @@ const explainer = `

What are Edge Functions?

Using JavaScript and TypeScript, Netlify Edge Functions give you the power to modify network requests to localize content, serve relevant ads, authenticate visitors, A/B test content, and much more! And this all happens at the Edge — directly from the worldwide location closest to each user.

-

To use Edge Functions on Netlify, add JavaScript or TypeScript files to an edge-functions directory in your project, and add [[edge_functions]] entries to your netlify.toml file.

+

To use Edge Functions on Netlify, add JavaScript or TypeScript files to an edge-functions directory in your project.

Learn more in the docs.

`; @@ -39,7 +39,9 @@ export default function layout(data) { ${data.content}

- ${data.url.pathname !== "/" ? `Explore more examples` : ""} + ${ + data.url.pathname !== "/" ? `Explore more examples` : "" + }

${data.url.pathname !== "/" ? explainer : ""} diff --git a/netlify.toml b/netlify.toml index c5b9639..ae0c4a5 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,119 +1,19 @@ [dev] - framework = "#static" +framework = "#static" [build] - command = "echo No build for this site, we are living on the edge" - publish = "public" +command = "echo No build for this site, we are living on the edge" +publish = "public" [context.production] - environment = { MY_IMPORTANT_VARIABLE = "this is a very important secret" } +environment = { MY_IMPORTANT_VARIABLE = "this is a very important secret" } -# The URL for each edge function -[[edge_functions]] - function = "transform" - path = "/*" - -[[edge_functions]] - function = "set-response-header" - path = "/*" -[[edge_functions]] - function = "set-request-header" - path = "/*" +[[redirects]] +from = "/img/og/:text" +to = "https://res.cloudinary.com/netlify/image/upload/c_fit,g_west,h_400,co_rgb:FFFFFFFF,l_text:netlify.com:Pacaembu-Bold.ttf_57::text,w_1053,x_46/v1619123320/netlify.com/default-og-background-learn-more.png" +status = 200 [[edge_functions]] - function = "include" + function = "transform" path = "/*" - -[[edge_functions]] - path = "/hello" - function = "hello" - -[[edge_functions]] - path = "/geolocation" - function = "geolocation" - -[[edge_functions]] - path = "/json" - function = "json" - -[[edge_functions]] - path = "/cookies" - function = "cookies" - -[[edge_functions]] - path = "/rewrite" - function = "rewrite" - -[[edge_functions]] - path = "/abtest" - function = "abtest" - -[[edge_functions]] - path = "/image-internal" - function = "image-internal" - -[[edge_functions]] - path = "/image-external" - function = "image-external" - -[[edge_functions]] - path = "/log" - function = "log" - -[[edge_functions]] - path = "/country-block" - function = "country-block" - -[[edge_functions]] - path = "/localized-content" - function = "localized-content" - -[[edge_functions]] - path = "/fetch-joke" - function = "proxy-requests" - -[[edge_functions]] - path = "/environment" - function = "environment" - -[[edge_functions]] - path = "/error" - function = "error" - -[[edge_functions]] - path = "/long-running" - function = "long-running" - -[[edge_functions]] - path = "/sse" - function = "sse" - -[[edge_functions]] - path = "/context-site" - function = "context-site" - -[[edge_functions]] - path = "/wasm" - function = "wasm" - -# Serve pages explaining each example -[[edge_functions]] - path = "/example/*" - function = "[page]" - -# Serve our index page -[[edge_functions]] - path = "/" - function = "[page]" - -[[redirects]] - from = "/img/og/:text" - to = "https://res.cloudinary.com/netlify/image/upload/c_fit,g_west,h_400,co_rgb:FFFFFFFF,l_text:netlify.com:Pacaembu-Bold.ttf_57::text,w_1053,x_46/v1619123320/netlify.com/default-og-background-learn-more.png" - status = 200 - - - - - - diff --git a/netlify/edge-functions/[page].js b/netlify/edge-functions/[page].js index c9a1f7d..7327927 100644 --- a/netlify/edge-functions/[page].js +++ b/netlify/edge-functions/[page].js @@ -8,12 +8,14 @@ import layout from "../../components/layout.js"; import pageHome from "../../pages/home/index.js"; import pageHello from "../../pages/hello/index.js"; import pageTransform from "../../pages/transform/index.js"; +import pageHtmlrewriter from "../../pages/htmlrewriter/index.js"; import pageInclude from "../../pages/include/index.js"; import pageRewrite from "../../pages/rewrite/index.js"; import pageGeolocation from "../../pages/geolocation/index.js"; import pageJson from "../../pages/json/index.js"; import pageSetRequestHeader from "../../pages/set-request-header/index.js"; import pageSetResponseHeader from "../../pages/set-response-header/index.js"; +import pageMethod from "../../pages/method/index.js"; import pageCookiesSet from "../../pages/cookies-set/index.js"; import pageCookiesRead from "../../pages/cookies-read/index.js"; import pageCookiesDelete from "../../pages/cookies-delete/index.js"; @@ -39,6 +41,7 @@ const pages = { json: pageJson, "set-response-header": pageSetResponseHeader, "set-request-header": pageSetRequestHeader, + method: pageMethod, "cookies-set": pageCookiesSet, "cookies-read": pageCookiesRead, "cookies-delete": pageCookiesDelete, @@ -53,14 +56,15 @@ const pages = { environment: pageEnvironment, "uncaught-exceptions": pageUncaughtExceptions, "context-site": pageContextSite, - "wasm": pageWasm, + wasm: pageWasm, "server-sent-events": pageSse, "long-running": pageLongRunning, + htmlrewriter: pageHtmlrewriter, }; export default (request, context) => { const url = new URL(request.url); - const path = url.pathname.split("/example/")[1] || "home"; + const path = context.params?.page || "home"; console.log(`serve page for ${url} `); @@ -77,3 +81,7 @@ export default (request, context) => { headers: { "content-type": "text/html" }, }); }; + +export const config = { + path: ["/", "/example/:page"], +}; diff --git a/netlify/edge-functions/abtest.ts b/netlify/edge-functions/abtest.ts index 6840777..bbcfa4d 100644 --- a/netlify/edge-functions/abtest.ts +++ b/netlify/edge-functions/abtest.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { // look for existing "test_bucket" cookie @@ -29,3 +29,7 @@ export default async (request: Request, context: Context) => { `Congratulations! You have been assigned ${bucketName} **${newBucketValue}**. View your browser cookies to check it out!`, ); }; + +export const config: Config = { + path: "/abtest", +}; \ No newline at end of file diff --git a/netlify/edge-functions/context-site.ts b/netlify/edge-functions/context-site.ts index 122432f..163d0ee 100644 --- a/netlify/edge-functions/context-site.ts +++ b/netlify/edge-functions/context-site.ts @@ -1,5 +1,9 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { return new Response(`Hello from ${context.site.name}!`); }; + +export const config: Config = { + path: "/context-site", +}; \ No newline at end of file diff --git a/netlify/edge-functions/cookies.ts b/netlify/edge-functions/cookies.ts index 494d999..92bc8fb 100644 --- a/netlify/edge-functions/cookies.ts +++ b/netlify/edge-functions/cookies.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { const url = new URL(request.url); @@ -27,3 +27,7 @@ export default async (request: Request, context: Context) => { return new Response(message); }; + +export const config: Config = { + path: "/cookies", +}; \ No newline at end of file diff --git a/netlify/edge-functions/country-block.ts b/netlify/edge-functions/country-block.ts index 9cee3cd..661d5ca 100644 --- a/netlify/edge-functions/country-block.ts +++ b/netlify/edge-functions/country-block.ts @@ -1,4 +1,4 @@ -import { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { // Here's what's available on context.geo @@ -32,3 +32,7 @@ export default async (request: Request, context: Context) => { headers: { "content-type": "text/html" }, }); }; + +export const config: Config = { + path: "/country-block", +}; \ No newline at end of file diff --git a/netlify/edge-functions/environment.ts b/netlify/edge-functions/environment.ts index 7f93604..9fb6d75 100644 --- a/netlify/edge-functions/environment.ts +++ b/netlify/edge-functions/environment.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { const value = Netlify.env.get("MY_IMPORTANT_VARIABLE"); @@ -7,3 +7,7 @@ export default async (request: Request, context: Context) => { headers: { "content-type": "text/html" }, }); }; + +export const config: Config = { + path: "/environment", +}; \ No newline at end of file diff --git a/netlify/edge-functions/error.ts b/netlify/edge-functions/error.ts index 94c50aa..a60cd44 100644 --- a/netlify/edge-functions/error.ts +++ b/netlify/edge-functions/error.ts @@ -1,3 +1,7 @@ export default async () => { throw new Error("💥"); }; + +export const config = { + path: "/error", +}; \ No newline at end of file diff --git a/netlify/edge-functions/geolocation.ts b/netlify/edge-functions/geolocation.ts index 3a582ef..cc7f694 100644 --- a/netlify/edge-functions/geolocation.ts +++ b/netlify/edge-functions/geolocation.ts @@ -1,4 +1,5 @@ -import { Context } from "https://edge.netlify.com/"; +import type { Config, Context } from "@netlify/edge-functions"; + export default async (request: Request, context: Context) => { // Here's what's available on context.geo @@ -24,3 +25,7 @@ export default async (request: Request, context: Context) => { geo: context.geo, }); }; + +export const config: Config = { + path: "/geolocation", +}; \ No newline at end of file diff --git a/netlify/edge-functions/hello.js b/netlify/edge-functions/hello.js index 4de5bcc..0d6ce29 100644 --- a/netlify/edge-functions/hello.js +++ b/netlify/edge-functions/hello.js @@ -3,3 +3,7 @@ export default async (request) => { headers: { "content-type": "text/html" }, }); }; + +export const config = { + path: "/hello", +}; \ No newline at end of file diff --git a/netlify/edge-functions/htmlrewriter.ts b/netlify/edge-functions/htmlrewriter.ts new file mode 100644 index 0000000..aa70a8a --- /dev/null +++ b/netlify/edge-functions/htmlrewriter.ts @@ -0,0 +1,35 @@ +import { Config, Context } from "@netlify/edge-functions"; +import { HTMLRewriter } from "https://ghuc.cc/worker-tools/html-rewriter/index.ts"; + +export default async function handler(request: Request, context: Context) { + const url = new URL(request.url); + if (!url.searchParams.has("catify")) { + return; + } + + const location = context?.geo?.city; + + const response = await context.next(); + const rewriter = new HTMLRewriter() + .on("#location", { + element: (element) => { + element.setInnerContent(`Catified for a visitor in ${location}`); + }, + }) + .on("img[catify]", { + element: (element) => { + const width = element.getAttribute("width") ?? 800; + const height = element.getAttribute("height") ?? 600; + element.setAttribute( + "src", + `https://placekitten.com/${width}/${height}` + ); + element.setAttribute("alt", "A random cat"); + }, + }); + return rewriter.transform(response); +} + +export const config: Config = { + path: "/a-static-page", +}; diff --git a/netlify/edge-functions/image-external.ts b/netlify/edge-functions/image-external.ts index 85fdcc6..627359e 100644 --- a/netlify/edge-functions/image-external.ts +++ b/netlify/edge-functions/image-external.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; // Let's serve an image of a kitten from the internet @@ -9,3 +9,7 @@ export default async (request: Request, context: Context) => { const kitten = await fetch("https://github.com/service/https://placekitten.com/g/300/300"); return kitten; }; + +export const config: Config = { + path: "/image-external", +}; \ No newline at end of file diff --git a/netlify/edge-functions/image-internal.ts b/netlify/edge-functions/image-internal.ts index a6b820b..25400c4 100644 --- a/netlify/edge-functions/image-internal.ts +++ b/netlify/edge-functions/image-internal.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; // Let's serve an image that's stored in the repo // by rewriting the URL. @@ -6,3 +6,7 @@ import type { Context } from "https://edge.netlify.com/"; export default async (request: Request, context: Context) => { return new URL("/apple-touch-icon.png", request.url); }; + +export const config: Config = { + path: "/image-internal", +}; \ No newline at end of file diff --git a/netlify/edge-functions/include.ts b/netlify/edge-functions/include.ts index 74ae860..9e2440b 100644 --- a/netlify/edge-functions/include.ts +++ b/netlify/edge-functions/include.ts @@ -1,4 +1,4 @@ -import { Context } from "https://edge.netlify.com/"; +import { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { @@ -23,3 +23,7 @@ export default async (request: Request, context: Context) => { const updatedPage = page.replace(regex, pricingContent); return new Response(updatedPage, response); }; + +export const config: Config = { + path: "/*", +}; \ No newline at end of file diff --git a/netlify/edge-functions/json.ts b/netlify/edge-functions/json.ts index 95624ab..6a9a3ef 100644 --- a/netlify/edge-functions/json.ts +++ b/netlify/edge-functions/json.ts @@ -1,5 +1,9 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { return Response.json({ hello: "world" }); }; + +export const config: Config = { + path: "/json", +}; \ No newline at end of file diff --git a/netlify/edge-functions/localized-content.js b/netlify/edge-functions/localized-content.js index 7a81319..575cefd 100644 --- a/netlify/edge-functions/localized-content.js +++ b/netlify/edge-functions/localized-content.js @@ -14,3 +14,7 @@ export default async (request, context) => { headers: { "content-type": "text/html" }, }); }; + +export const config = { + path: "/localized-content", +}; \ No newline at end of file diff --git a/netlify/edge-functions/log.ts b/netlify/edge-functions/log.ts index 289a8fd..0fe4962 100644 --- a/netlify/edge-functions/log.ts +++ b/netlify/edge-functions/log.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { console.log("Hello from the logging service"); @@ -7,3 +7,7 @@ export default async (request: Request, context: Context) => { headers: { "content-type": "text/html" }, }); }; + +export const config: Config = { + path: "/log", +}; \ No newline at end of file diff --git a/netlify/edge-functions/long-running.ts b/netlify/edge-functions/long-running.ts index 2a2560e..06d5508 100644 --- a/netlify/edge-functions/long-running.ts +++ b/netlify/edge-functions/long-running.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; function doSomethingSlow(): Promise { return new Promise((resolve) => { @@ -22,3 +22,7 @@ export default (request: Request, context: Context) => { }, }); }; + +export const config: Config = { + path: "/long-running", +}; \ No newline at end of file diff --git a/netlify/edge-functions/method.ts b/netlify/edge-functions/method.ts new file mode 100644 index 0000000..48238f9 --- /dev/null +++ b/netlify/edge-functions/method.ts @@ -0,0 +1,11 @@ +import type { Config, Context } from "@netlify/edge-functions"; + +export default async (request: Request, context: Context) => { + + return new Response(`This is a response to a ${request.method} request`) +}; + +export const config: Config = { + path: "/method", + method: ["POST", "PUT"] +} diff --git a/netlify/edge-functions/proxy-requests.ts b/netlify/edge-functions/proxy-requests.ts index 677346f..9d3f6eb 100644 --- a/netlify/edge-functions/proxy-requests.ts +++ b/netlify/edge-functions/proxy-requests.ts @@ -1,4 +1,4 @@ -import { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { @@ -10,3 +10,7 @@ export default async (request: Request, context: Context) => { const jsonData = await joke.json(); return Response.json(jsonData); }; + +export const config: Config = { + path: "/fetch-joke", +}; \ No newline at end of file diff --git a/netlify/edge-functions/rewrite.ts b/netlify/edge-functions/rewrite.ts index 4a644c5..d4ec350 100644 --- a/netlify/edge-functions/rewrite.ts +++ b/netlify/edge-functions/rewrite.ts @@ -1,5 +1,8 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { return new URL("/something-to-serve-with-a-rewrite", request.url); }; +export const config: Config = { + path: "/rewrite", +}; \ No newline at end of file diff --git a/netlify/edge-functions/set-request-header.ts b/netlify/edge-functions/set-request-header.ts index 10c96f9..9af3346 100644 --- a/netlify/edge-functions/set-request-header.ts +++ b/netlify/edge-functions/set-request-header.ts @@ -1,5 +1,9 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { request.headers.set("X-Your-Custom-Header", "Your custom header value"); }; + +export const config: Config = { + path: "/*", +}; \ No newline at end of file diff --git a/netlify/edge-functions/set-response-header.ts b/netlify/edge-functions/set-response-header.ts index 3487d05..d2527e2 100644 --- a/netlify/edge-functions/set-response-header.ts +++ b/netlify/edge-functions/set-response-header.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { const url = new URL(request.url); @@ -13,3 +13,7 @@ export default async (request: Request, context: Context) => { response.headers.set("X-Your-Custom-Header", "Your custom header value"); return response; }; + +export const config: Config = { + path: "/*", +}; \ No newline at end of file diff --git a/netlify/edge-functions/sse.ts b/netlify/edge-functions/sse.ts index c8fdcc8..c26f532 100644 --- a/netlify/edge-functions/sse.ts +++ b/netlify/edge-functions/sse.ts @@ -1,4 +1,4 @@ -import type { Context } from "https://edge.netlify.com/"; +import type { Context, Config } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { let index = 0 @@ -16,3 +16,7 @@ export default async (request: Request, context: Context) => { }, }); }; + +export const config: Config = { + path: "/sse", +}; \ No newline at end of file diff --git a/netlify/edge-functions/transform.ts b/netlify/edge-functions/transform.ts index 7e09a6d..41f92f1 100644 --- a/netlify/edge-functions/transform.ts +++ b/netlify/edge-functions/transform.ts @@ -1,4 +1,4 @@ -import { Context } from "https://edge.netlify.com/"; +import type { Config, Context } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { const url = new URL(request.url); diff --git a/netlify/edge-functions/wasm.ts b/netlify/edge-functions/wasm.ts index c346b68..8f2d2fd 100644 --- a/netlify/edge-functions/wasm.ts +++ b/netlify/edge-functions/wasm.ts @@ -14,4 +14,8 @@ const main = wasmInstance.exports.main as CallableFunction; export default async () => { return new Response(`The answer is ${main().toString()}`); -} \ No newline at end of file +} + +export const config = { + path: "/wasm", +}; \ No newline at end of file diff --git a/pages/abtest/index.js b/pages/abtest/index.js index 730120a..21c7f3e 100644 --- a/pages/abtest/index.js +++ b/pages/abtest/index.js @@ -11,7 +11,7 @@ export default {

Visitors can then be redirected to different pages, depending on the bucket and cookie they were assigned.

You could even use A/B testing in combination with Geolocation at The Edge!

-
import type { Context } from "https://edge.netlify.com/";
+      
import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   // look for existing "test_bucket" cookie
diff --git a/pages/context-site/README.md b/pages/context-site/README.md
index cf7b89a..fa3546d 100644
--- a/pages/context-site/README.md
+++ b/pages/context-site/README.md
@@ -9,7 +9,7 @@ Netlify Edge Functions give access to site information via `context.site`.
 Edge Functions are files held in the `netlify/edge-functions` directory.
 
 ```ts
-import type { Context } from "https://edge.netlify.com/";
+import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   return new Response(`Hello from ${context.site.name}!`);
diff --git a/pages/context-site/index.js b/pages/context-site/index.js
index e68d3be..e297982 100644
--- a/pages/context-site/index.js
+++ b/pages/context-site/index.js
@@ -8,7 +8,7 @@ export default {
     

Access Site Information from Edge Functions

Netlify Edge Functions give access to site information via context.site.

-
import type { Context } from "https://edge.netlify.com/";
+      
import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   return new Response(\`Hello from \${context.site.name}!\`);
diff --git a/pages/cookies-delete/README.md b/pages/cookies-delete/README.md
index 04a72a0..cabb018 100644
--- a/pages/cookies-delete/README.md
+++ b/pages/cookies-delete/README.md
@@ -9,7 +9,7 @@ Manipulate HTTP cookies
 Edge Functions are files held in the `netlify/edge-functions` directory.
 
 ```ts
-import type { Context } from "https://edge.netlify.com/";
+import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   // Set a cookie
diff --git a/pages/cookies-delete/index.js b/pages/cookies-delete/index.js
index 4e75bcb..af83ef5 100644
--- a/pages/cookies-delete/index.js
+++ b/pages/cookies-delete/index.js
@@ -8,7 +8,7 @@ export default {
     

Delete HTTP cookies

Use an Edge Function to delete cookies.

-
import type { Context } from "https://edge.netlify.com/";
+      
import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   // Delete a cookie
diff --git a/pages/cookies-read/README.md b/pages/cookies-read/README.md
index 2f8ef06..cd2cdc3 100644
--- a/pages/cookies-read/README.md
+++ b/pages/cookies-read/README.md
@@ -9,7 +9,7 @@ Manipulate HTTP cookies
 Edge Functions are files held in the `netlify/edge-functions` directory.
 
 ```ts
-import type { Context } from "https://edge.netlify.com/";
+import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   // Set a cookie
diff --git a/pages/cookies-read/index.js b/pages/cookies-read/index.js
index d566930..0bcacee 100644
--- a/pages/cookies-read/index.js
+++ b/pages/cookies-read/index.js
@@ -8,7 +8,7 @@ export default {
     

Reading cookies

Use an Edge Function to read and manage HTTP cookies.

-
import type { Context } from "https://edge.netlify.com/";
+      
import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {  
   // Read the value of a cookie
diff --git a/pages/cookies-set/README.md b/pages/cookies-set/README.md
index 506e18a..128e438 100644
--- a/pages/cookies-set/README.md
+++ b/pages/cookies-set/README.md
@@ -9,7 +9,7 @@ Manipulate HTTP cookies
 Edge Functions are files held in the `netlify/edge-functions` directory.
 
 ```ts
-import type { Context } from "https://edge.netlify.com/";
+import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   // Set a cookie
diff --git a/pages/cookies-set/index.js b/pages/cookies-set/index.js
index 8a69ddd..6ea18cc 100644
--- a/pages/cookies-set/index.js
+++ b/pages/cookies-set/index.js
@@ -8,7 +8,7 @@ export default {
     

Setting cookies

Use an Edge Function to create and manage HTTP cookies.

-
import type { Context } from "https://edge.netlify.com/";
+      
import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {  
   // Set a cookie    
diff --git a/pages/country-block/index.js b/pages/country-block/index.js
index 7ac904a..56840eb 100644
--- a/pages/country-block/index.js
+++ b/pages/country-block/index.js
@@ -10,7 +10,7 @@ export default {
       

You can use geolocation data to identify a user's country and block content if required.

Geolocation information is available on the Context.geo object.

-
import { Context } from "https://edge.netlify.com/";
+      
import { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   const BLOCKED_COUNTRY_CODE = "GB";
diff --git a/pages/environment/README.md b/pages/environment/README.md
index ca75d43..a9d42cf 100644
--- a/pages/environment/README.md
+++ b/pages/environment/README.md
@@ -10,7 +10,7 @@ use the `Netlify.env` API.
 Edge Functions are files held in the `netlify/edge-functions` directory.
 
 ```ts
-import type { Context } from "https://edge.netlify.com/";
+import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   const value = Netlify.env.get("MY_IMPORTANT_VARIABLE");
diff --git a/pages/environment/index.js b/pages/environment/index.js
index 6cc0655..483594d 100644
--- a/pages/environment/index.js
+++ b/pages/environment/index.js
@@ -9,7 +9,7 @@ export default {
       

Use environment variables

To access your Netlify environment variables in Edge Functions, use the Netlify.env API.

-
import type { Context } from "https://edge.netlify.com/";
+      
import type { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   const value = Netlify.env.get("MY_IMPORTANT_VARIABLE");
diff --git a/pages/geolocation/index.js b/pages/geolocation/index.js
index 58d5603..2768c46 100644
--- a/pages/geolocation/index.js
+++ b/pages/geolocation/index.js
@@ -22,7 +22,7 @@ export default {
       
       

Geolocation information is available on the Context.geo object.

-
import { Context } from "https://edge.netlify.com/";
+      
import { Context } from "@netlify/edge-functions";
 
 export default async (request: Request, context: Context) => {
   // Here's what's available on context.geo
diff --git a/pages/home/index.js b/pages/home/index.js
index 76a5165..0d4cd10 100644
--- a/pages/home/index.js
+++ b/pages/home/index.js
@@ -1,8 +1,9 @@
 export default {
   title: "Home",
-  metaDescription: "Explore our library of Edge Function examples and deploy your own to Netlify.",
+  metaDescription:
+    "Explore our library of Edge Function examples and deploy your own to Netlify.",
   page: function () {
-    return /* html */`
+    return /* html */ `
     

Examples

@@ -26,19 +27,21 @@ export default {

  • Proxy requests to another source
  • - +
    -

    HTTP Headers

    +

    HTTP Headers and Methods

    - +

    Transforming responses

    diff --git a/pages/htmlrewriter/README.md b/pages/htmlrewriter/README.md new file mode 100644 index 0000000..d5672e9 --- /dev/null +++ b/pages/htmlrewriter/README.md @@ -0,0 +1,66 @@ +![Netlify examples](https://user-images.githubusercontent.com/5865/159468750-df1c2783-39b2-40da-9c0f-971f72a7ea3f.png) + +# Transform HTML responses with Netlify Edge Functions and HTMLRewriter + +You can use Edge Functions with the HTMLRewriter library to transform HTML +responses. HTMLRewriter uses WebAssembly to parse a response stream, so is very +efficient. It can parse large HTML pages with minimal overhead, and is a better +choice than using a string transform in most cases. It has an API that uses +familiar CSS selectors to target elements, and can be used to add, remove, or +modify elements. + +In this example, we transform an HTML page, replacing the `src` of `` tags +with a placeholder image. We also add content with the user's location. This +shows how to do user personalization when the pages may be static. + +## Code example + +Edge Functions are files held in the `netlify/edge-functions` directory. + +```ts +import { Config, Context } from "@netlify/edge-functions"; +import { HTMLRewriter } from "https://ghuc.cc/worker-tools/html-rewriter/index.ts"; + +export default async function handler(request: Request, context: Context) { + const url = new URL(request.url); + // Only run if the `catify` query parameter is set + if (!url.searchParams.has("catify")) { + return; + } + + const location = context?.geo?.city; + + const response = await context.next(); + const rewriter = new HTMLRewriter() + .on("#location", { + element: (element) => { + element.setInnerContent(`Catified for a visitor in ${location}`); + }, + }) + .on("img[catify]", { + element: (element) => { + const width = element.getAttribute("width") ?? 800; + const height = element.getAttribute("height") ?? 600; + element.setAttribute( + "src", + `https://placekitten.com/${width}/${height}` + ); + element.setAttribute("alt", "A random cat"); + }, + }); + return rewriter.transform(response); +} +``` + +- [Explore the code for this Edge Function](../../netlify/edge-functions/htmlrewriter.ts) + +## View this example on the web + +- https://edge-functions-examples.netlify.app/example/htmlrewriter/ + +## Deploy to Netlify + +You can deploy this and all the other examples in this repo as a site of your +own to explore and experiment with, by clicking this button. + +[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/netlify/edge-functions-examples&utm_campaign=devex&utm_source=edge-functions-examples&utm_medium=web&utm_content=Deploy%20Edge%20Functions%20Examples%20to%20Netlify) diff --git a/pages/htmlrewriter/index.js b/pages/htmlrewriter/index.js new file mode 100644 index 0000000..5295fcf --- /dev/null +++ b/pages/htmlrewriter/index.js @@ -0,0 +1,67 @@ +import repoLink from "../../components/repo-link.js"; + +export default { + title: "Transform HTML Response stream", + metaDescription: "Dynamically transform any HTML response at the edge.", + page: function () { + return /* html */ ` +
    +

    Transform HTML responses with Netlify Edge Functions and HTMLRewriter

    +

    + You can use Edge Functions with the HTMLRewriter library to transform HTML + responses. HTMLRewriter uses WebAssembly to parse a response stream, so is very + efficient. It can parse large HTML pages with minimal overhead, and is a better + choice than using a string transform in most cases. It has an API that uses + familiar CSS selectors to target elements, and can be used to add, remove, or + modify elements. +

    +

    + In this example, we transform an HTML page, replacing the src of tags + with a placeholder image. We also add content with the user's location. This + shows how to do user personalization when the pages may be static. +

    + +
    import { Config, Context } from "@netlify/edge-functions";
    +import { HTMLRewriter } from "https://ghuc.cc/worker-tools/html-rewriter/index.ts";
    +
    +export default async function handler(request: Request, context: Context) {
    +  const url = new URL(request.url);
    +  // Only run if the catify query parameter is set
    +  if (!url.searchParams.has("catify")) {
    +    return;
    +  }
    +
    +  const location = context?.geo?.city;
    +
    +  const response = await context.next();
    +  const rewriter = new HTMLRewriter()
    +    .on("#location", {
    +      element: (element) => {
    +        element.setInnerContent(\`Catified for a visitor in \${location}\`);
    +      },
    +    })
    +    .on("img[catify]", {
    +      element: (element) => {
    +        const width = element.getAttribute("width") ?? 800;
    +        const height = element.getAttribute("height") ?? 600;
    +        element.setAttribute(
    +          "src",
    +          \`https://placekitten.com/\${width}/\${height}\`
    +        );
    +        element.setAttribute("alt", "A random cat");
    +      },
    +    });
    +  return rewriter.transform(response);
    +}
    +
    + +

    See this in action

    + +
    + `; + }, +}; diff --git a/pages/image/index.js b/pages/image/index.js index 9cc5321..a9c45f3 100644 --- a/pages/image/index.js +++ b/pages/image/index.js @@ -9,7 +9,7 @@ export default {

    Image Response

    You can use Edge Functions to return an image.

    -
    import type { Context } from "https://edge.netlify.com/";
    +      
    import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
     
    diff --git a/pages/include/README.md b/pages/include/README.md
    index 712c0e5..b26bd62 100644
    --- a/pages/include/README.md
    +++ b/pages/include/README.md
    @@ -13,7 +13,7 @@ some other content.
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import { Context } from "https://edge.netlify.com/";
    +import { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       // Get the page content
    diff --git a/pages/include/index.js b/pages/include/index.js
    index 651638d..da6d628 100644
    --- a/pages/include/index.js
    +++ b/pages/include/index.js
    @@ -14,7 +14,7 @@ export default {
           In this example, we look for an {{INCLUDE_PRICE_INFO}} placeholder in our response, and replace it with some other content.
         

    -
    import { Context } from "https://edge.netlify.com/";
    +    
    import { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       
    diff --git a/pages/json/README.md b/pages/json/README.md
    index e33eaa4..16ec252 100644
    --- a/pages/json/README.md
    +++ b/pages/json/README.md
    @@ -10,7 +10,7 @@ You can use Edge Functions to return a JSON response by returning `Response.json
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import type { Context } from "https://edge.netlify.com/";
    +import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       return Response.json({ hello: "world" });
    diff --git a/pages/json/index.js b/pages/json/index.js
    index 35711bd..373e304 100644
    --- a/pages/json/index.js
    +++ b/pages/json/index.js
    @@ -10,7 +10,7 @@ export default {
           

    You can use Edge Functions to return a JSON response by returning Response.json() with a JavaScript object — no need to JSON.stringify!

    In this example, we return a JSON object containing hello: "world".

    -
    import type { Context } from "https://edge.netlify.com/";
    +      
    import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       return Response.json({ hello: "world" });
    diff --git a/pages/log/README.md b/pages/log/README.md
    index 892bcd6..e888cd9 100644
    --- a/pages/log/README.md
    +++ b/pages/log/README.md
    @@ -9,7 +9,7 @@ Output content to the logs from an Edge Function using `console.log()`.
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import type { Context } from "https://edge.netlify.com/";
    +import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       console.log("Hello from the logging service");
    diff --git a/pages/log/index.js b/pages/log/index.js
    index b9878c1..9195afd 100644
    --- a/pages/log/index.js
    +++ b/pages/log/index.js
    @@ -8,7 +8,7 @@ export default {
         

    Logging with Edge Functions

    You can output content to the logs during the execution of your Edge Function.

    -
    import type { Context } from "https://edge.netlify.com/";
    +      
    import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       console.log("Hello from the logging service");
    diff --git a/pages/long-running/README.md b/pages/long-running/README.md
    index 5807f96..8855c75 100644
    --- a/pages/long-running/README.md
    +++ b/pages/long-running/README.md
    @@ -9,7 +9,7 @@ Edge Functions are limited to 50ms of CPU time, but this does not include time s
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import type { Context } from "https://edge.netlify.com/";
    +import type { Context } from "@netlify/edge-functions";
     
     export default (request: Request, context: Context) => {
       const body = new ReadableStream({
    diff --git a/pages/long-running/index.js b/pages/long-running/index.js
    index 364ac7b..5632f14 100644
    --- a/pages/long-running/index.js
    +++ b/pages/long-running/index.js
    @@ -13,7 +13,7 @@ export default {
             from the function and write to it when you have the data.
           

    -
    import type { Context } from "https://edge.netlify.com/";
    +      
    import type { Context } from "@netlify/edge-functions";
     
     export default (request: Request, context: Context) => {
       const body = new ReadableStream({
    diff --git a/pages/method/README.md b/pages/method/README.md
    new file mode 100644
    index 0000000..9e673de
    --- /dev/null
    +++ b/pages/method/README.md
    @@ -0,0 +1,48 @@
    +![Netlify examples](https://user-images.githubusercontent.com/5865/159468750-df1c2783-39b2-40da-9c0f-971f72a7ea3f.png)
    +
    +# Configure for specific HTTP methods
    +
    +With in-source configuration, you can restrict Edge Functions to respond to certain HTTP methods.
    +
    +## Code example
    +
    +Edge Functions are files held in the `netlify/edge-functions` directory.
    +
    +```ts
    +import type { Config, Context } from "@netlify/edge-functions";
    +
    +export default async (request: Request, context: Context) => {
    +
    +  return new Response(`This is a response to a ${request.method} request`)
    +};
    +
    +export const config: Config = {
    +  method: ["POST", "PUT"]
    +}
    +```
    +
    +- [Explore the code for this Edge Function](../../netlify/edge-functions/method.ts)
    +
    +## View this example on the web
    +
    +- https://edge-functions-examples.netlify.app/example/method
    +
    +When viewed through a browser, the URL should 404. To validate that it works, you can use a CURL by running the following command in a terminal:
    +
    +```
    +curl -X POST https://edge-functions-examples.netlify.app/example/method
    +```
    +
    +or
    +
    +```
    +curl -X PUT https://edge-functions-examples.netlify.app/example/method
    +```
    +
    +
    +## Deploy to Netlify
    +
    +You can deploy this and all the other examples in this repo as a site of your own to explore and experiment with, by
    +clicking this button.
    +
    +[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/netlify/edge-functions-examples&utm_campaign=devex&utm_source=edge-functions-examples&utm_medium=web&utm_content=Deploy%20Edge%20Functions%20Examples%20to%20Netlify)
    diff --git a/pages/method/index.js b/pages/method/index.js
    new file mode 100644
    index 0000000..544afd4
    --- /dev/null
    +++ b/pages/method/index.js
    @@ -0,0 +1,39 @@
    +import repoLink from "../../components/repo-link.js";
    +
    +export default {
    +  title: "Configure for HTTP Methods",
    +  metaDescription: "Configure Edge Functions to execute for certain HTTP methods.",
    +  page: function() {
    +    return `
    +    
    +

    Configure for specific HTTP methods

    +

    + With in-source configuration, you can restrict Edge Functions to respond to certain HTTP methods. +

    +

    + In this example, we set up an Edge Function to execute for a PUT or POST request. +

    + +
    import type { Config, Context } from "@netlify/edge-functions";
    +
    +export default async (request: Request, context: Context) => {
    +  return new Response(\`This is a response to a \${request.method}\`)
    +};
    +
    +export const config: Config = {
    +  method: ["POST", "PUT"]
    +}
    +

    See this in action

    +

    Since the Edge Function is configured to respond to PUT and POST, accessing the Edge Function through a browser will result in a 404. +
    To validate that the Edge Function works, you can use cURL in your terminal: + +
    curl -X POST https://edge-functions-examples.netlify.app/example/method +
    curl -X PUT https://edge-functions-examples.netlify.app/example/method +

    +
      +
    • ${repoLink("method.ts")}
    • +
    +
    + `; + }, +}; diff --git a/pages/proxy-requests/README.md b/pages/proxy-requests/README.md index 59cd0fc..5cc4851 100644 --- a/pages/proxy-requests/README.md +++ b/pages/proxy-requests/README.md @@ -10,7 +10,7 @@ Edge Function. Edge Functions are files held in the `netlify/edge-functions` directory. ```ts -import { Context } from "https://edge.netlify.com/"; +import { Context } from "@netlify/edge-functions"; export default async (request: Request, context: Context) => { const joke = await fetch("https://github.com/service/https://icanhazdadjoke.com/", { diff --git a/pages/proxy-requests/index.js b/pages/proxy-requests/index.js index bd7ffff..95334e8 100644 --- a/pages/proxy-requests/index.js +++ b/pages/proxy-requests/index.js @@ -8,7 +8,7 @@ export default {

    Proxy requests to another source

    You can use fetch() to make requests to other sources via an Edge Function.

    -
    import { Context } from "https://edge.netlify.com/";
    +      
    import { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
     
    diff --git a/pages/rewrite/README.md b/pages/rewrite/README.md
    index 94406de..7c31cbc 100644
    --- a/pages/rewrite/README.md
    +++ b/pages/rewrite/README.md
    @@ -9,7 +9,7 @@ You can rewrite requests on one URL to resources available on another URL using
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import type { Context } from "https://edge.netlify.com/";
    +import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       return new URL("/something-to-serve-with-a-rewrite", request.url);
    diff --git a/pages/rewrite/index.js b/pages/rewrite/index.js
    index 2c7e227..f9fc7b7 100644
    --- a/pages/rewrite/index.js
    +++ b/pages/rewrite/index.js
    @@ -8,7 +8,7 @@ export default {
         

    Rewrite with Edge Functions

    You can rewrite requests on one URL to resources available on another URL using an Edge Function.

    -
    import type { Context } from "https://edge.netlify.com/";
    +      
    import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       return new URL("/something-to-serve-with-a-rewrite", request.url);
    diff --git a/pages/server-sent-events/README.md b/pages/server-sent-events/README.md
    index 654e14d..2d9260b 100644
    --- a/pages/server-sent-events/README.md
    +++ b/pages/server-sent-events/README.md
    @@ -9,7 +9,7 @@ You can use Edge Functions to create a long-running service that can stream data
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import type { Context } from "https://edge.netlify.com/";
    +import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       let index = 0
    diff --git a/pages/server-sent-events/index.js b/pages/server-sent-events/index.js
    index 0cffbaf..4a3bdb2 100644
    --- a/pages/server-sent-events/index.js
    +++ b/pages/server-sent-events/index.js
    @@ -12,7 +12,7 @@ export default {
           This means you can create a long-running service that can stream data to the browser.
           

    -
    import type { Context } from "https://edge.netlify.com/";
    +      
    import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       let index = 0
    diff --git a/pages/set-request-header/README.md b/pages/set-request-header/README.md
    index 6089798..148ace1 100644
    --- a/pages/set-request-header/README.md
    +++ b/pages/set-request-header/README.md
    @@ -9,7 +9,7 @@ Use an Edge Function to add HTTP headers to any HTTP request at The Edge.
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import type { Context } from "https://edge.netlify.com/";
    +import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       const response = await context.next();
    diff --git a/pages/set-request-header/index.js b/pages/set-request-header/index.js
    index 3d4d37e..84fead2 100644
    --- a/pages/set-request-header/index.js
    +++ b/pages/set-request-header/index.js
    @@ -8,7 +8,7 @@ export default {
         

    Set custom HTTP request headers with an Edge Function

    Use an Edge Function to add HTTP headers to any HTTP request.

    -
    import type { Context } from "https://edge.netlify.com/";
    +      
    import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       request.headers.set("X-Your-Custom-Header", "Your custom header value");
    diff --git a/pages/set-response-header/README.md b/pages/set-response-header/README.md
    index c8f9b8c..383c13c 100644
    --- a/pages/set-response-header/README.md
    +++ b/pages/set-response-header/README.md
    @@ -9,7 +9,7 @@ Use an Edge Function to add HTTP headers to any HTTP response at The Edge.
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import type { Context } from "https://edge.netlify.com/";
    +import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       const response = await context.next();
    diff --git a/pages/set-response-header/index.js b/pages/set-response-header/index.js
    index 7d5b367..e689e06 100644
    --- a/pages/set-response-header/index.js
    +++ b/pages/set-response-header/index.js
    @@ -8,7 +8,7 @@ export default {
         

    Set custom HTTP response headers with an Edge Function

    Use an Edge Function to add HTTP headers to any HTTP response.

    -
    import type { Context } from "https://edge.netlify.com/";
    +      
    import type { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       const response = await context.next();
    diff --git a/pages/transform/README.md b/pages/transform/README.md
    index 1a77f4a..de9405e 100644
    --- a/pages/transform/README.md
    +++ b/pages/transform/README.md
    @@ -11,7 +11,7 @@ request to `/hello` with JavaScript's toUpperCase() function, using
     Edge Functions are files held in the `netlify/edge-functions` directory.
     
     ```ts
    -import { Context } from "https://edge.netlify.com/";
    +import { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       const url = new URL(request.url);
    diff --git a/pages/transform/index.js b/pages/transform/index.js
    index 0e6eaf7..f1ff79f 100644
    --- a/pages/transform/index.js
    +++ b/pages/transform/index.js
    @@ -10,8 +10,10 @@ export default {
           

    You can use Edge Functions to transform the content of an HTTP response. In this example, we transform the response of a request to /hello with a toUpperCase() function, using the query parameter method=transform.

    +

    This is a simple example, and for more complex transformations you may want to use HTMLRewriter. +

    -
    import { Context } from "https://edge.netlify.com/";
    +      
    import { Context } from "@netlify/edge-functions";
     
     export default async (request: Request, context: Context) => {
       const url = new URL(request.url);
    @@ -27,11 +29,8 @@ export default async (request: Request, context: Context) => {
     };
     
    -

    This transform Edge Function is set up to run using the method=transform query parameter on any URL, using this entry in the netlify.toml file:

    +

    This transform Edge Function is set up to run using the method=transform query parameter on any URL

    -
    [[edge_functions]]
    -  function = "transform"
    -  path = "/*"

    See this in action

    • View the original response from /hello without a transform
    • diff --git a/public/a-static-page.html b/public/a-static-page.html new file mode 100644 index 0000000..3806c9d --- /dev/null +++ b/public/a-static-page.html @@ -0,0 +1,25 @@ + + + + + + + + Catify + + + + +

      A static page

      +

      + Catify me +

      + random image + random image + + + \ No newline at end of file