Forget a server — bring your static website to life with AWS S3, Lambda, and API Gateway

Source: AWS

When developing a static website for a business, portfolio, or even an application, there is a point every developer will reach:


Keep in mind, a website will almost always need some sort of functional component. Whether it be a contact form or feedback prompt, this functionality is crucial to nearly every business website.

In a traditional sense, this would require spinning up a server. An entire backend server for something as simple as a contact form seems quite overkill, and, well — it is. At least in the modern cloud era. Using AWS Lambda and API Gateway for backend services, we can forget about needing a backend server. We can hook into AWS Simple Email Service to handle the emailing portion from our backend. As for static website hosting, AWS S3 will provide us this functionality. Not only is this solution more practical, it is much more cost effective.

Source: AWS Architecture Blog

Note: In order to host a static website with AWS S3 using your own domain, you will need to ensure your domain is created with or transferred to AWS Route 53. For a detailed guide on setting up AWS S3 static website hosting, see:

Okay, let’s get started. First, we need a very simple contact form:

A simple HTML contact form implementation.

In the example above, the form will ask for a full name, email, and message. When the form is submitted, the data is sent to the backend using JavaScript.

READ:  How to host a website in local IIS in windows 10

Now that we have a simple form on our S3 static website, let’s configure our AWS Lambda backend to handle requests sent from the contact form. From the AWS Lambda console, click the Create Function button. For this demonstration, let’s choose the Author from scratch option. This will serve as a Hello World blueprint for our new Lambda function.

Choose the Author from scratch option.

Under Basic information, enter a name of your choice. For this demonstration, let’s use the Node.js 14.x runtime.

Be sure to assign your Lambda function sufficient permissions to send emails through AWS SES. The remaining settings will be left as default. When the function has been created, we can now begin building our handler function. Below is the snippet of code we will use for this example:

Let’s break it down.

  • Import the aws-sdk and and use the SES object to send the email to our desired account.
  • Build the response object we want to send back upon successful execution of our Lambda function.
  • In our handler function, call the sendEmail function. The sendEmail function calls on our ses object to send an email containing the data specified in the emailData variable.

It’s really as simple as that. The only thing left to do is set up API Gateway to make the Lambda function accessible from our contact form.

Note: When using the Test option in Lambda, you may receive an error due to a difference in the event variable when using it. Simply change JSON.parse(event.body) to event when using the Test option only.

In the API Gateway console, choose Create API. For this demonstration, let’s use the HTTP API type.

READ:  World leading higher education information and services Home News Blogs Courses Jobs
Choose the HTTP API type.

On the next screen under Integrations, choose Lambda from the dropdown list. Choose the region your new Lambda function resides, and then choose the Lambda function name. Enter an API name of your choice and click Next.

In the next step, we need to configure the route for our new API. Under Method choose POST. For this demonstration, let’s leave the stage configuration as default. Review and Create the new API. On the next screen, save the Invoke URL under the Stages section. This is the URL for our new contact endpoint.

The Invoke URL under the Stages section above is the URL our frontend will use to make contact requests.

Congratulations, you’re finished! The serverless architecture is set up and we are ready to update our contact form with our new URL and test it out: