Tips for terminating a request with Edge Functions

A common use case in Edge Functions is to intercept the request only when certain conditions are met, or otherwise let it follow its normal course. In this post I want to share some tips on how you can do that in the most performant way.

If you want just a quick summary, here’s a rule of thumb:

  • If you want to terminate the execution of the edge function and let the request follow its normal course, return undefined (or simply use an empty return statement);
  • If you want to access the underlying contents of the path you’re processing, use context.next().

Let’s look at a couple of examples.

Terminate the execution

:white_check_mark:

Using an empty return is the most performant way of terminating the execution and letting the request proceed.

import { Context } from "https://edge.netlify.com"

export default async (req: Request, context: Context) => {
  if (context.country.code !== "PT") {
    return
  }

  return new Response("Olá!")
}

:x:

In this case, we don’t need access to the underlying response, so calling context.next() is unnecessary and slows down the overall execution.

import { Context } from "https://edge.netlify.com"

export default async (req: Request, context: Context) => {
  if (context.country.code !== "PT") {
    return context.next() // <-- Don't do this!
  }

  return new Response("Olá!")
}

Transform a response

:white_check_mark:

In this example, we need access to the underlying response in order to transform it. This is a good use case for context.next().

import { Context } from "https://edge.netlify.com"

export default async (req: Request, context: Context) => {
  if (context.country.code !== "PT") {
    return
  }

  const res = await context.next()
  const text = await res.text()

  return new Response(text.replaceAll("Hello", "Olá"), res)
}
2 Likes

This was ridiculously useful – could this be noted in the docs somewhere?

Hi @eduardoboucas how does caching play with a straight up “return” response?

Can I set the cache so that next time the function doesnt even have to run?

You can use the cache, but not with an empty return.

First of all, you need to configure your edge function to use caching. Once you do that, you can cache a response by setting the appropriate cache-control headers.

If your edge function has an empty return, it is not setting those headers, so it will always run.

To achieve the behaviour you described, you’d need to access the response within the edge function, append the cache-control headers you want, and then return it. Something like:

import type { Context, Config } from "@netlify/edge-functions"

export default async (req: Request, context: Context) => {
  const res = await context.next()

  res.headers.set("cache-control", "public, s-maxage=3600")
  
  return res
}

export const config: Config = {
  cache: "manual",
  path: "/hello"
}

I hope that helps!

Thanks for the feedback! I’ve shared this with the team and we’ll look into ways of making this clearer in the documentation.

Thanks @eduardoboucas, one more thought, what if I want to return a redirect or a 404, can that also be cached?

Yes, that should work!

1 Like