How to send emails with Edge Functions on Supabase

Adeola Adeyemo J.
4 min readAug 10, 2023

A simple tutorial on Edge Functions — Part 2

Photo by Carl Nenzen Loven on Unsplash

This is Part 2 of my Supabase tutorial series. If you haven’t, please check out the previous article, How to create a contact form with Supabase & Next JS. We will use the same Supabase project and API keys.

In this tutorial, we learn how to create an edge function to send emails. We will walk through how to trigger email notifications when the contacts table has a new entry in the next article.

To follow along, you need basic knowledge of JavaScript. You can also check it out on Github.

Edge functions

Edge Functions are server-side TypeScript functions, distributed globally at the edge — close to your users. They can be used for listening to webhooks or integrating your Supabase project with third-parties like Stripe.”

We can deploy server-side code that works as API endpoints. If you have worked with Firebase or Netlify, this is similar to how Cloud functions and Netlify functions work.

Initialize supabase locally

To create an edge function in our project, we need the supabase CLI. If you don’t have this installed, follow the instructions here . Check that you have the latest version installed too to avoid spending 2 days debugging like me.

brew install supabase/tap/supabase

Next, initialize a supabase project and follow the instructions.

supabase init

Next, link your supabase database to your local project. Replace [reference_id] with the project reference, you can check yours in the General tab of the project settings page. The database password is in the Database tab also.

supabase link --project-ref [reference_id]

Once this is done, we should have a supabase folder at the root of our local project with the config.toml file.

Create function

Next, we create an edge function named email.

supabase functions new email

This creates an email function. This function is situated in supabase/functions folder. All our functions will be added to this folder.

The default email function should look like this.

Next, modify the email function to be functional. Feel free to use any email service you like. For the sake of this example, we will use resend. Thankfully, there is a guide here.

import { serve } from "https://deno.land/std@0.131.0/http/server.ts";

console.log(`Function "email" up and running!`);

const RESEND_API_KEY = Deno.env.get("RESEND_API_KEY");

serve(async (request: Request): Promise<Response> => {
const { email, body, name }: { email: string; body: string; name: string } =
await request.json();

if (!email?.length) {
return new Response(JSON.stringify({ error: "No email provided" }), { status: 400 });
}

try {
const res = await fetch("https://api.resend.com/emails", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${RESEND_API_KEY}`,
},
body: JSON.stringify({
from: "hello@deolaj.com",
to: email,
subject: "You have a new message!",
html: `
<div>
<p>Hi Deola,</p>
<p>${body}</p>
<p>From: ${name}</p>
</div>
`,
}),
});

if (!res.ok) {
return new Response(JSON.stringify({ error: "An error occurred" }), { status: 500 });
}

const data = await res.json();

return new Response(JSON.stringify(data), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});
} catch (error: any) {
return new Response(JSON.stringify({ error: error?.message }), { status: 500 });
}
});

A few things to note here. First, notice the email, body, and name values from our contacts table in Part 1 of this series. We also use RESEND_API_KEY from our environment variables (more on this in the next section).

Environment variables

We need to set the RESEND_API_KEY variable to use. There are two ways to do this.

The first involves creating an .env file in the root supabase folder. Remember to add .env to your .gitignore file. This will add all the variables in the .env file.

supabase secrets set --env-file ./supabase/.env

Alternatively, you can set the variables individually

supabase secrets set RESEND_API_KEY=value

Note that some environment variables have been set by default. To view all environment variables, run

supabase secrets list

For a more comprehensive explanation, check the functions guide or CLI documentation.

Deployment

To deploy the email function, simply run

supabase functions deploy email

Feel free to invoke your function in your terminal to test. Replace the FUNCTION_URL , API_KEY , and email with yours.

curl --request POST 'FUNCTION_URL' \
--header 'Authorization: Bearer API_KEY' \
--header 'Content-Type: application/json' \
--data '{"email":"hello@deolaj.com", "name":"Test person", "body":"This is a test email"}'

To invoke your function locally, check this guide

Conclusion

I hope this tutorial helps to get started with edge functions on supabase.

Next, we learn how to trigger email notifications when our contact form (from Part 1) gets a new submission.

Follow along to Part 3, How to trigger email notifications on a contact form with Supabase

Originally posted in my portfolio notes

--

--

Adeola Adeyemo J.

Senior Frontend / Founding Engineer | Open to new opportunities | https://deolaj.com