Sending Contact Form Emails with Netlify Serverless Functions

Sending Contact Form Emails with Netlify Serverless Functions

Sending Contact Form Emails with Netlify Serverless Functions

📩 Sending Contact Form Emails Using Netlify Serverless Functions

At Bluesunrise, we believe that modern web apps should be fast, secure, and server-free whenever possible. When building our new Astro website, we wanted to include a Contact Us form that sends an email — without setting up a custom server.

Thanks to Netlify Serverless Functions, Google reCAPTCHA, and AWS SES, we were able to do this in a simple, scalable way — with zero backend code running 24/7.

🧱 The Goal

We wanted our contact form to:

✨ The Frontend: Astro Contact Form

We built our form using Astro components like Input, Textarea, Radio, and Select. When a user clicks Submit, we collect the form data and send it to a Netlify serverless function via fetch():

const response = await fetch("/.netlify/functions/send-email", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(data),
});

We also included Google reCAPTCHA to prevent spam and bots. The token is sent along with the request and verified on the server side.

🔐 The Serverless Function: send-email.js

This Netlify Function is triggered on form submission. Here’s what it does:

  1. Parses the form
const { name, email, phone, message, captchaToken } = JSON.parse(event.body);
  1. Validates reCAPTCHA with Google
const captchaResponse = await fetch(
  "https://www.google.com/recaptcha/api/siteverify",
  {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: `secret=${captchaSecret}&response=${captchaToken}`,
  },
);

If verification fails, we return a 403 error.

  1. Sends the email using AWS SES
AWS.config.update({
  accessKeyId: process.env.NETLIFY_AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.NETLIFY_AWS_SECRET_ACCESS_KEY,
});

Then we used the AWS SDK to send the message:

await ses.sendEmail(params).promise();

The HTML message contains all the form fields and is formatted nicely for email readers.

✅ Why We Love This Approach

Using Netlify Functions for form submission offers many benefits:

✔ No backend server to maintain. No need for Express, Node, or deployment pipelines. The function runs on demand.

✔ Pay only for usage. Netlify includes generous limits for functions in the free tier. We only pay if traffic grows significantly.

✔ Easy integration with Astro. Astro doesn’t have a backend runtime — but Netlify Functions give you just enough server logic when needed.

✔ Secure and scalable. We store our keys in Netlify environment variables and validate users with reCAPTCHA.

🧪 Things to Watch For

✅ Make sure your AWS SES account is verified and in production mode.

✅ Use Netlify’s environment variables for secret keys (never commit them).

✅ If needed, log errors from the serverless function for easier debugging.

🧠 Final Thoughts

This setup proves that you don’t need a traditional server to build secure, full-featured websites. With Astro, Netlify, and a bit of AWS, you can build fast, beautiful websites with powerful backend features — without leaving the JAMstack.