Skip to content
Switch branches/tags
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Static Site Mailer

A Serverless service for submitting contact forms on static sites. It uses AWS Lambda in Node to send AWS Simple Email Service emails to verified addresses. This repo can be forked to deploy your own service for use on your own static site.

For a beginner-friendly guide on setting up Serverless, AWS, and this service follow along in my Smashing Magazine article: Building a Serverless Contact Form for your Static Site.

Setup and Requirements

Setup requires an AWS account and a local Node + Yarn environment.

Installing This Service

  1. Run yarn
  2. Set Up Your AWS Account
  3. Set Up AWS SES

Setting Up Your AWS Account

The Serverless Framework has recorded a video walk-through for setting up AWS credentials, but I've listed the steps here as well.

  1. Sign Up for an AWS account or log in if you already have one.
  2. In the AWS search bar, search for "IAM".
  3. On the IAM page, click on "Users" on the sidebar, then the "Add user" button.
  4. On the Add user page, give the user a name -- something like "serverless" is appropriate. Check "Programmatic access" under Access type then click next.
  5. On the permissions screen, click on the "Attach existing policies directly" tab, search for "AdministratorAccess" in the list, check it, and click next.
  6. On the review screen you should see your user name, with "Programmatic access", and "AdministratorAccess", then create the user.
  7. The confirmation screen shows the user "Access key ID" and "Secret access key", you'll need these to provide the Serverless Framework with access. In your CLI, type yarn sls config credentials --provider aws --key YOUR_ACCESS_KEY_ID --secret YOUR_SECRET_ACCESS_KEY, replacing YOUR_ACCESS_KEY_ID and YOUR_SECRET_ACCESS_KEY with the keys on the confirmation screen.

Setting Up AWS Simple Email Service

  1. Click Console Home in the top left corner.
  2. On home page, in the AWS search bar, search for "Simple Email Service".
  3. On the SES Home page, click on "Email Addresses" in the sidebar.
  4. On the Email Addresses listing page, click the "Verify a New Email Address" button.
  5. In the dialog window, type your email address then click "Verify This Email Address".
  6. You'll receive an email in moments containing a link to verify the address. Click on the link to complete the process.

Setting Up the Form

Static Site Mailer expects the form to submit stringified JSON and returns a JSON response. It's best used with AJAX calls.

Form Paramters

The Static Site Mailer expects the following parameters to be present in your form:

Name Description
ses_address The verified AWS SES email address to send the email from
send_to The verified AWS SES email address to send the email to
subject The sending email subject line
name The name field on the contact form
reply_to The email field on the contact form, also used in the reply to field in the email
message The message text area on the contact form
honeypot An optional honeypot filter. If the honeypot has any value, the form will be rejected

The form action must be the full URL of the service and the method must be set to POST.

Form Example

<form action="{{ SERVICE URL }}" method="POST">
  <input type="hidden" name="ses_address" value="{{ VERIFIED SES SENDING FROM EMAIL }}" />
  <input type="hidden" name="send_to" value="{{ VERIFIED SES SENDING TO EMAIL }}" />
  <input type="hidden" name="subject" value="{{ EMAIL SUBJECT }}" />
  <input type="input" name="honeypot" value="" style="display: none" tabindex="-1" autocomplete="off">
    <input type="text" name="name" required>
    <input type="email" name="reply_to" required>
    <textarea name="message" required></textarea>
  <button type="submit">Send Message</button>

Form AJAX Example

To submit your form using AJAX, you can add the following code to your static site. This JavaScript syntax is compatible with the latest browsers.

(() => {
  const form = document.querySelector('form');

  form.onsubmit = e => {
    // Escape if the honeypot has been filled
    if (!!form.children.namedItem('honeypot').value) return;

    // Prepare data to send
    const data = {};
    const formElements = Array.from(form); => (data[] = input.value));

    // Construct an HTTP request
    var xhr = new XMLHttpRequest();, form.action, true);
    xhr.setRequestHeader('Accept', 'application/json; charset=utf-8');
    xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');

    // Send the collected data as JSON

    // Callback function
    xhr.onloadend = response => {
      if ( === 200) {
        // The form submission was successful
      } else {
        // The form submission failed
        // Static Site Mailer returns a JSON object with error messages on
        // JSON.parse(
        // console.error(JSON.parse(;

Setting Up CORS

If the service URL isn't your own domain, you'll need to set up CORS. For use with a single domain, it's easiest to set it up in the sendEmail response as a hard-coded value. In handler.js, it should be set up as your own domain.

sendEmail(formData, function(err, data) {
  const response = {
    headers: {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': '',

To accept all domains, simply change 'Access-Control-Allow-Origin' to *, as in 'Access-Control-Allow-Origin': '*' or filter through white-listed domains.


Run yarn deploy to deploy the entire service or yarn deploy-submit-form to deploy the SubmitForm handler itself.

Yarn Scripts

Command Action
deploy Deploys entire Static Site Mailer Architecture
deploy-submit-form Deploys the SubmitForm handler/function
invoke Invokes SubmitForm from production
invoke-local Invokes SubmitForm from local
logs Prints production logs
serverless Shortcut for local Serverless CLI package
sls Shortcut for local Serverless CLI package
service-info Prints Static Site Mailer Serice Information
test Runs all the tests
test-honeypot Returns the response when a honeypot is present
test-ses Returns the reponse when the ses_address param is missing
test-send-to Returns the response when the send_to param is missing



A contact form mailer using Serverless for static sites



No releases published


No packages published