Let’s Learn Netlify Edge Functions
with Jason Lengstorf
In a solo episode, Jason will dig into the new Netlify Edge Functions. Learn what edge computing enables, what you can build with it, and how to get started.
Resources & Links
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everyone, and welcome to another episode of Learn With Jason. Today on the show, we are hanging out with me. Sorry. You're stuck with just me. I promise I'm going to try to be a third as entertaining as our usual experts. But today is going to be a fun one, because I haven't had a chance to really play with Netlify Edge Functions yet. Some of you may know, over the last year I transitioned into a role as a VP at Netlify. And that means that really the only coding I get to do these days is on this show, which is why I love this show so much. Because, you know, I'm a tinkerer at heart, I love playing with things, I love getting a chance to try new things out and learn more about what's going on in the ecosystem. Not only because it's important for my job, because Netlify is very focused on the ecosystem at large, but also because that's where I find the most joy. And as you all know, I love playing around, being goofy, being weird, and messing with things on the Internet is one of my favorite ways to get more joy into my life. So, you know, this show is basically that source of joy for me. So, thank you all for hanging out. Very excited to be here and having a good time. And thank you, what up, Ben, I see you raided with some friends. Thank you very much. I see some other folks in the chat, as well. Ryan, Adrian, who else is in here? I see Nikki is here, Dave. What's up, y'all? Thank you very much. Yeah, I got a Centered T-shirt. I actually got a whole box. Hold on, let me show you.
This is cool. I got this box from the team. Wait, am I -- come on, get me in focus. There we go. Yeah, so, this is a box from the team at Centered that is just like a felt box. Says "enjoy your flow" inside. And there's a cable on one side. And the idea is, that when you're working, you put your phone into this box, and then don't look at it. So, look, we can do this. Watch. We're going to do a little flow. So, here's my phone, goes in the box. Bada bing, bada boom, no distractions. Yeah, thanks to the Centered team for sending that. We also have someone from the Centered team on the show. Let me find a link, actually. It was a fun discussion. We messed with dynamic images, but also had kind of mini podcast at the beginning about staying focused, which I loved. You suggesting that we store grapes in the felt box, is that the idea? I mean, there's fabric in there. That seems like a bad idea. (Laughing)
There are a couple ways we can look at this. I'm going to -- definitely going to need these docs. Let's start here. So, the docs are in Netlify Labs. They are in a beta, so they are on by default, but they are still -- there's some stuff we have to figure out, we're getting feedback, everything. So, this is a great time, if you all want to dig in to try this and send feedback. We've got this feedback button right here, if you want to let us know, send it to forums. There's also in Netlify Labs, have you all ever seen Netlify Labs? Check this out. If we go to Netlify.com, and you go to here. There's Netlify Labs. And in here you can see features that you can turn on. So I've, obviously, I'm opted into everything, as I do. But you can choose which ones you want to be opted into. We have schedule functions, where you can run something on a schedule, visualize your Lighthouse score of your website, which is pretty dang cool. Netlify graph, and Edge functions are apparently not opt-outable, so they are not shown in the list, but they are enabled. So, what should we do first? I'm going to read the docs, how about that. Let's start by reading the docs here and figure out how to get started within Edge Function. And I thought it would be fun, let's see if we can get them running on my personal site. So, I'm going to go into GitHub, then go to here. I'm going to pull the changes. And I can open this up. I'm going to have to remember what framework I built my site in. Okay, it was built in Eleventy. So, I can -- there's an Eleventy edge experimental feature, but I'm going to build in straight Edge Functions so it's not framework specific today. I want to just play with a couple of the features. I'm most interested in -- well, let's look at my site and try to decide what we should build.
Here's my site. We have a couple things. We have this boop drop. So, that's fun. We've got my bio checker, this photo thing, where we can choose a different photo. Got links to stuff like this, like my egghead, "Learn with Jason," and front end masters. Newsletter opt in, and then my posts. So, there are a few things that we can do here. I think what would be fun to start is what if we just put in, like, something about where you are. I feel like the Gio is really, really cool. Maybe what we could do is -- oh, this could be interesting. I wonder if -- Amazon links, one of these has to be an Amazon link. I think I did everything through other services. Oh, if I go to Amazon.com, but I'm in the UK. If I just go to.uk, does it work? It does. Oh, okay. I have an idea. Let's do this. Let's see if we can localize our Amazon links and, yeah, all right. That sounds like fun. Because that's going to give us a couple things we have to figure out, too. The data that comes in is from this uses page, which is actually the notion API. Apparently, I hard-coded that. Oh, I should go fix that. So, we have all of this, and I need to transform it. So, I need to transform this API uses call and see if we can localize Amazon links. Okay, first and foremost, let's see if we can get Edge Functions running at all. I'm going to get the latest version of Netlify CLI. Localize and time stamp that, great idea. If I get my Netlify version, I'm at 9.16.6. Is that right? So I'm just double checking. I did the thing. Where are you coming from? Going to make me do this whole thing? I am using Volta, and I can't remember why. Somebody told me it was good, and I tried it, and I didn't bother changing anything else.
Let's see, Netlify Edge Functions, import map. All right. What else do we get in here. Let's run Netlify help again. Netlify Functions help. Is that wrong? Doesn't look like it does Edge Functions yet. Might be in here, but I haven't tried it yet. We'll create it as if it doesn't. Let me get in here, use this. Next thing I need to do is get back into docs. We have to configure it, so we need to tell our Edge Functions how to work. So, down at bottom, I can drop in my Edge Function. And if we hit the path, we want to run hello, which is this one here. So, I'm going to save that, and then I'm going to run Netlify dev again. Hey, what's up, Alex and friends, thank you for joining. We are talking about Edge Functions today. So, we just set up our first Edge Function, which lives at hello JS. Using the standard response object, and we configured our site to run at the slash test. It's going to execute the hello function, so let's give it a shot. Okay, so, there is our first Edge Function, running in the wild. And I believe if we update this, it updates in realtime. So, we've got local development, and we are -- yeah, just going great. Kevin asking if I can talk with my sweet voice. Does that mean -- are you asking for my late night radio voice?
Who are the -- what's going on, DevRel -- what are we talking about? You know, the sweet voice. I don't know, but I hope that was it. Let's see here. So, we have running function, but now I want to do more. So, let's go play with the docs and figure out what we can find. So, we have our local testing, running that. I'm happy about it. We can deploy it. I'm not doing that just yet. We don't need to monitor just yet. I want to look at the API. What do we got? So, we have the Netlify-specific context object. Then we have web APIs and Deno APIs. I am running it with Netlify dev. So, I ran Netlify dev up here, and it picks up our functions server and all those things, and then it should say -- maybe it says somewhere down here that it picked up an Edge Function. Oh, yeah, loaded Edge Function hello. And then it also shows us when we call that Edge Function. So, this is Netlify dev, just the Netlify CLI, which is -- this is like one of the reasons that I love this CLI so much, is that it did all of this for me, so I didn't have to. It auto-detected Eleventy, set up a setup, build command, environment variables, and running our edge functions for us, so I don't have to do any stuff. Ben has a great answer to the question about is the Edge Functions like APIs. Edge Functions can be like APIs. Check this out, if I wanted this to be my API, I can do something like this. Let's do -- there's a helper in here that I want. We can go to geo, JSON.
All right, so, if I get my context object, which comes in as the second argument, then I can do something like -- -- what if I do JSON, and I say -- is that going to work? Try it, see what happens. I'm going to come back here. JSON is not a constructor. Okay. What if I do it like this? There we go. Netlify-specific content is going to short circuit setting up the object. Now this could be an API. Now I can change my Netlify to say API get greeting. Then if I come out here, API get greeting, I might have to restart for this to work. Now we've built a tiny Edge API. This would mean that anything that gets requested from here, the actual processing would get done at the Edge node instead of at a serverless function at a data center. So, the tradeoffs, if I'm making a call to a data center, I'm not getting rid of the round trip, so it might make sense to keep that in a serverless function, where the serverless function is in the same data center as the planet scale database, so that communication between the two is going to be just ultra fast. But if I'm doing something like, say, transforming the response, putting it right next to the user is a great way to think about that. Let's see. Can you JSON stringify the context? I think that's what this is doing here with the context.JSON.
Why did Netlify choose Deno for Edge Functions? We chose it, because it's built on open standards, and we thought it was important to build on standards that are open documentation. So, response.JSON, or the response object in general, and the request object that goes with it, are the building blocks for Edge Functions and what Deno runs on. So, this felt important to us, because it means no vendor locking. It means once you build these, anybody else that uses the same standards, you'll be able to port your stuff over very, very easily. It even does your laundry. You're correct.
Deno the better node? I don't think so. I think they are different approaches. Ryan started both, I should say, and I think Node has been wonderful for what it is. And I think Deno has a different application and has a lot of potential for solving a different problem. Let's see. Scrolling on down. Can these Edge functions run on Deno, do we need to consider whether or not we can test them locally with Deno? No, because the Netlify CLI will test them for you. I don't have Deno installed on my computer. I am running Deno through Netlify CLI. And, so, you get to use these features, where we're running Edge Functions. That is happening based on our CLI. I didn't have to install Deno or anything. So, let's play a little bit more, because what I want to do next is start actually messing with responses, because I think the thing that's really cool here is, like, what Edge Functions are is not a serverless where it's the end. It can be something entirely different. I'll keep that over there for reference if we need it. But let me set up another one that is -- let's do like a geo -- geo Amazon.js. This is what we'll build for the rest of the thing. I'm going to do an async function, get context, and try and do stuff with it.
But the first thing that I want to show is that I can do something like Edge Function. Then I can return request, I think. You know what, I'm not going to check the docs. I'm just going to run it. Then I'm going to go to Netlify and duplicate this block, but I'm going to actually have it hit the path of -- where's my -- I have my uses stuff loading in here. Yeah, API uses. This brings in my notion. I have a notion doc. Let me go over here. Where is it? Yeah, check this out. This is the document that I use in motion to track what I use. I've got it in a database, have it broken down by gear, software, and each of these is tagged with what kind of stuff it is and all those other bits, right, the things that are important to share. Then this is the notion API, and out here I use that API to build out this page, which displays all my gear. And all my software with a chance to get details if you want it. If you want to look at that page, it lives here. And I want to transform this, because there are going to be links that are Amazon.com. Looks like there's only two of them, but that's okay. That means this is a low-risk experiment, and I want to replace the .com. Yeah, Audrew, no guest today, you're stuck with just me. So what I want to do, do geo Amazon. Let's run this and see what happens. Doesn't look like it picked up the new Edge Function. Stop to get it.
So, we have translations. So, let's look at how we actually get this stuff. Context, geo, country, code. And country name. Okay. So, I'm just going to pull this directly out. Let's drop this in. And then I want to log these. So, we're going to do countryCode and countryName. Just going to dump this into the console and see where it thinks I'm from. Go here, log it. And we get I'm in the U.S. Okay, that makes sense. How fine grain is the geo? API, Netlify, geo. We get a city. Oh. Yes. All right, I want the city, too. So, let's get the city. Log it. Head over here. Okay, I'm not getting the city. I wonder if that's because it's local dev. Or if I'm using it wrong. Also possible that I'm using it wrong. Let's go back. Geo, city, country, code name. Yeah, I'm using it wrong. Try that one more time. Portland. Very cool. Like, extremely cool that this is working. Could you run a traditional cloud function on an Edge function to improve performance? Yes, you can, and people are already doing it. So, check this out. Remix Edge Functions. Where is it? Remix on Netlify.
So, Edge functions. If you want to learn more, you can actually run Edge Functions to do your whole Remix deployment. I believe Astro is also working on this. We're trying to get quick support out, as well, and Nuxt has the nitro, Nuxt 3 Nitro has Edge Function support. Eleventy has an Edge Function, I believe, yeah, there's a whole plug-in for that if you want to use it. But let's -- yeah, let me just get to the Edge Functions. And there's a blog post. Here. Has a list of -- here we go. Hydrogen, the Shopify framework, Nuxt, Eleventy, Remix, will all run on Netlify Edge Functions in some capacity. So, you can use those today. Nuxt Middleware can run on Edge Functions. Svelte kit -- oh, look. Here it is. So, this is a Svelte app running on the edge, and you can -- that one doesn't work, I don't know why. Pretty exciting stuff going on. You can find some articles. Actually, one of the best people to follow for this stuff is Matt Kane, who spends a ton of time looking on just upstream everywhere. He was at Gatsby, contributed a ton to Gatsby. He's also contributed to Nuxt, Svelte, Astro. He's everywhere. Just a good source of information about all of these pieces and how they work. So, good follow there if you're trying to get more details about how the Edge works. So, all right. So, the next thing that I want to do is figure out how to make this work. So, let's figure out some, like -- do Amazon extensions. And we're going to -- so, U.S. is a com. We're going to have to do it this way. Amazon.com. Then we have UK. Somebody give me another one. Who's in the chat from not the U.S. or UK. What's your Amazon link? Canada. Good call. We'll do Amazon.ca. And, yep, Japan is jp. Co.jp. There was another one, DE. Amazon.de. And one more India. India, Amazon.in. I'm going to stop there, because I'll have to do more of these later. Let's do this. I'm going to get the AmazonTLDs and we're going to go with countryCode. Or U.S. We'll kind of fake it in there. Actually can even do this. Then we'll do one of these. Default to the U.S., but I don't have a fallback for it. We can drop in our Amazon TLD here. And what I'm going to do is also drop it in here. Let's see if we can make this work. So, I'm coming in with my local host here. And if I search for Amazon, we get a .com. Okay, that's good, that's me. Now, I can't turn on a VPN or I'll break the stream. So, I'm going to have to send this over to -- oh, nice, thanks, Tony, for the reference. We'll have to do PRs welcome here for that, so maybe there's -- pull this over. I have too many things now. I'm going to share this again, because I have a macro now that Aiden built for me. Aiden runs the show. To automatically drop these into a Discord channel, so they are easier to find. Here's all of our setup good, good, good. So, we're going to set up there. For now we're going to leave it where it is, and I want to deploy this. So, let's get it up on a -- get it up on a deploy preview. So, we're going to get, commit, and say feature, add geo support for Amazon links. Oh, a crap. Screwed that up. Didn't I, chat. So, I'm going to git push, and we'll do origin. Geo. And then what I want to do is do a GitHub PR create. Yes. I'm going to hit this. We'll say this pull request adds Edge Functions to localize Amazon links based on geo. All right. Now we have to remember how to exit. Control-X. Yes. And then you just hit enter and hope for the best. Now I'm going to submit. All right. Let's open up this PR and take a look. All right. That's building for us. If I go back to my account, I can see this site is building. Here's my deploy preview. Oh, that's cool. Totally do that. Have you all not heard this story? Blitz Jackson is my alter ego, I guess. I don't know. One time I was talking about needing to have a wrestler persona, like a finishing move, and we decided that my wrestler name would be Blitz Jackson. But then we also decided that sounded like a weatherman, so we figured out my pro wrestling persona is a disgruntled weatherman named Blitz Jackson. And my finishing move is, like, the scattered showers or something. I don't know exactly what that looks like. Maybe I get a bunch of chairs and I throw them in the air, and I kick somebody, so all the chairs fall. I don't know. But that's Blitz Jackson. Is this thing done building? Almost, almost. Oh, we're running a Lighthouse. Okay, so, that's building. Build script success.
I also want to show that Lighthouse thing, because it's super cool. Check this out. Now you can see your Lighthouse scores in here. That's a lot of fun. The Breezy Tornado. That is good, that is good. Call it the hailstorm, call it the flash flood. Or maybe, you know, maybe this is like more of a tech thing, where you have a lot of moves and not just one finisher. Anyway, should we look at this preview? Okay, here's my deploy preview. We can go to this test. What was the -- what was after this? Let's see. Do I need to fix anything to make this work? Oh, yeah. I made a greeting. Okay, that works. All right, that's good. Let's go to uses. All right, let's search for my Amazon.com. Yep, okay. And then let's go to uses. Here's what I want you all to try, chat, is get in here, and try this. Let me know. If you're not in the U.S., go. And the one that we want to look at is this mechanical boom arm. If you hover over this, you can see -- actually, probably can't see on mine. I have the window too small. Let's make this actually visible here. Okay, if you hover over here, bottom left, you can see that it's Amazon.com so, give it a shot and let me know if you're seeing a .co.uk. No! Try -- maybe it's causing problems. Is this one working? How are we doing on time? We got like 20 minutes to fix this. We're going to be golden. I'm going to go to my functions. Okay. So, one of these was called correctly. That was in the U.S. Oh, you know what I bet this is? I bet this is because I have the API deployed as an on-demand builder, and I bet I'm caching. Let's -- wait, no I don't. Hold on. No, this is not it. Here's my functions. Here's my uses. Here's the builder. So, let's not use the builder. Why would it come up undefined? I know why. I know why. Because I did the whole thing about not -- I need to escape to U.S., but also I need to log the country code. Commit fix. Fall back to U.S. Logging. Push. And we come back out here, we can go to our deploys. I'm going to cancel this one, because we don't actually need it anymore. I'm going to let this one run instead. This is going to use our cache. Is there an echo on the stream right now?
Oh, Tony, you were joking about -- okay, I understand. All right, this is going to build, it's going to run. While we're doing that, maybe we play this matching game. I love this matching game. I said I was good at it, and I'm definitely not. This one, this one? Yep, yep. No mistakes. All right, anyways, we're done. Let's go back to this deploy preview. Y'all give this a try and see what happens. That game got added -- was it the beginning this year? It was around the beginning of this year. This was a really great idea from the Netlify front end team. I'm not going to name names, because I can't remember exactly whose idea it was, but they all did a lot of work, and then the emoji in there rotate out every once in a while. So, around the holidays there was -- actually, this has been in longer than that, because there was one around the holidays that was snowmen and stuff like that. And then we swapped out for this. I think there's some plans to do some more. So, a lot of fun there. Still getting .com in Canada. Blast! All right, let's look at the Edge Function log again and get a sense of what's going on in here. Everybody hit these functions. Yeah, take it to the logs, y'all. Get to this. This one? You, you? All right. Are you showing up on the logs? Oh, you know what just happened in my head, and it was terrible? I just thought of that -- in my head I was thinking about where my logs at. I can't play any of this. But I can drop this. Get out of here, shush. I can't drop this here, y'all, if you want to watch. What's going on here, y'all? Am I getting crashes? Are things going wrong? No, I don't want it to run production. I want it to run -- this is my deploy logs for deploy ID. -- (No audio)
Okay, what is your malfunction? API uses -- so, this one is working. But I think what's happening is this one working if I go here? Amazon.com, Amazon.com. Okay, so, we have a couple problems here. One of which is I think I may have not -- geo Amazon. Right. So, this, we're going to -- yeah, let's debug the way that we know how. I didn't spot the raid. Is the raid what broke me? What's up, code it live, thank you all for coming and hanging out. I don't know if you watched me completely blow my camera setup, but both my camera and mic battery died at the same time. So, we went dark there for a minute. But we're back, we're working on Netlify Edge Functions today, and we are, I think, dangerously close to getting this to run. What we've done so far, let me push this and we'll walk through the code while we wait for it to build. What we've done is set up an Edge Function. A Netlify Edge Functions is a standards-based little piece of code that runs at the edge. Basically, where the CDN is. And what we're trying to figure out is how to get our geo data, our country code, to replace the Amazon link with a localized one for my uses page. So, if we look at my uses page here, a couple of these links are Amazon links. And I know that it bugs me whenever I click an Amazon link and it takes me to a co .uk, because I can't buy from there. So, what our function is intended to do is, if I can find it, get your country code out of the Edge Function, which is one of the things that Edge Functions do well. And find the right Amazon TLD, and then show that to people based on where they are in the world. And I just realized, no way this is going to work, because we're running at build time, which means there's no way this can function, because it's only going to build once and then show that URL. So, I need to actually transform the uses page, not the API response. Okay, y'all, we're getting there slowly. So, let's just try this one more time, but we're going to do it this time with -- let's get -- okay. So, we're going to run this locally. And we're going to update the Netlify.toml to target uses instead of the API. And that is not working. And it's not working, because I did it wrong, or because I -- let's see, what's missing? Host 888. It's not hitting that function. So, let's check here. Is it -- path uses, geo function Amazon. I'm going to stop and restart it. Wait, reload it. Refresh. It's not hitting. So, I want to stop this. Try it one more time. Because you should be running. Did I typo something, did y'all see anything? Let's try this API get greeting first. Our functions are running. Ha! Okay, here we go. But I set the wrong type. But that's okay. Because we knew -- so, now if I do this, it should show me the right thing, and it's replaced. Okay, all right. So, now we have this running dynamically, and theoretically, let's keep it theoretical at the moment. If I push this, finally -- oops,... how much time do we have? So little time. This is going to be our last try. Hope this works. Localize the right page. Okay, so, we're going to push. And we're going to go out to our deploys. We're going to watch this deploy go. And while we do that, we can look at -- for all the folks who joined late. This is the anatomy of an Edge Function. You export function, and you return something. So, what we've been using as our point of reference are these Netlify Edge Functions docs. So, you can jump in there and give that a try. And this has been a lot of fun. It's a lot to learn. You know, I was mentioning that really one of the only times I get to code these days is during streams. And, so, I've been learning right along with y'all. I haven't had a chance to really play with these very much at all. But what is exciting about these, if you get the chance to go and play, is check out this example repo. Because the team did a really good job on these. We've got a ton of examples. So, there's basic stuff, how to rewrite in proxy, you can set custom headers, you can do content transformation, geolocation, you can mess with cookies, you can do environment debugging. So, you have access to environment variables. There's a ton of stuff that will show you how to make this work. And if you just want to try it, deploy to Netlify and get this whole thing running on your own setup, so that you can use these. Let's see, our build is done. There it is. So, we're going to come back out here. I'm going to run this, and, hopefully -- refresh. Still not doing the thing. What is up, y'all, why is this not working? So, I'm doing something wrong with my deployment. Let me look at my Edge Functions here. So, it is grabbing the data, which is somewhat concerning. So, the call is working, but the replacement is not working. Which means I've done something wrong. And the thing that I've done wrong is what? Still get .com. Yeah. So, why, though? Hmm... I don't know. Don't know what I'm doing. Wondering if it's possible to get the geo information in the country main language. I don't know, actually. That would be something to maybe ask in the forums or something like that. How many minutes do we have? We have three minutes. And, so, we're getting this part -- probably what I'm doing is something in here that I need to address. It could be that the replacement on that much HTML is taking too long. So, it's exceeding our 50 millisecond time-out and just passing through the original response. It could also be that I need to use something like the HTML rewriter, which I, unfortunately, will not have time to try today. But there is a Wasm HTML rewriter. This is a cool thing here. So, this uses WebAssembly so that it's useful in any run time. What this would let us do is get the streaming response. We didn't look at this today, but Edge Functions can do streaming responses, and for each link, we'd look at the href and set the href to be the updated Amazon TLD. So, I will work on this a little bit and try to get it fixed. But, unfortunately, we are out of time today. So, what I'm going to do is one more shout-out to our captioner. We've had Ashly with us here all day today from White Coat Captioning. Thank you very much for being here. And that is made possible through the support of our sponsors, Netlify, Nx, and Backlight all kicking in to make this show more accessible to more people, which I very much appreciate. While you're checking out things on the site, you can go and check out the schedule. We've got some great stuff coming up. Later this week, we are going to have Johannes Schickling on about content layer, which is a way to take any type of content, Markdown, CMS stuff. (Audio error) (No audio)