Serverless contact form handling for static websites
Tags: serverless, javascript, tutorial, webdev
Published: 2019-07-29 12:54:21


When you’re making a static website, it means you don’t want to manage the server or want to save on costs. However, a static website can’t process contact forms, meaning you need a backend server to handle contact form requests. But if you need a server, then what is the logic of making a static website? So the simple solution is serverless contact forms.

## Why go serverless?
There are many benefits of making serverless applications, but in short, the main benefits are easy setup, no management, and less cost (free).

## Platform Selection
There are many ways to run serverless code like aws lambda, Google cloud functions, cloudflare workers. But I have selected the easiest way to run serverless code i.e. Google cloud functions.

[Google Cloud functions](https://cloud.google.com/functions/) allows you to trigger a function via HTTPS Request. It can also be done with aws lambda, but you need to set up API Gateway additional to trigger the function.

## Cost
Google cloud offers free 200,000 GHz-seconds of compute time, 5GB of Internet egress traffic, and 2 million invocations per month. 
https://cloud.google.com/functions/pricing

I’m using 256MB/0.4GHz runtime and it takes ~800ms to process a form.

This free quota is too much to handle a contact form submission.

0.4 x 0.8s = 0.32 GHz-seconds per invocation
200,000 / 0.32 = 625,000

You can handle 625,000 Successful form submissions per month for free*.

> *This is just a sample calculation and does not include email cost. Free resources are subjected to Google cloud policies.

## Setup

### Step 1: Create Project
(If you don’t have a Google cloud account, create one then create project)


![create project in google cloud account](https://thepracticaldev.s3.amazonaws.com/i/f9eayig8khuy1stqz733.png)


### Step 2: Create Function
Click on the menu icon on the left top corner. Scroll down and find Cloud Function under COMPUTE section.

![Create Cloud function](https://thepracticaldev.s3.amazonaws.com/i/nph0hmy8o0h0pifoqd0j.png)
Then click on the ‘*Create Function*’ button.


### Step 3: Configure Cloud function
Set function name (contact-form).

Allocate Memory (256MB is enough)

Set Trigger ‘HTTP’ — it works for https also.

Authentication is not required, so keep it checked to accept unauthenticated requests.

Source code can be added inline or ZIP file can be uploaded. You can find zip file here https://github.com/bansal-io/serverless-contact-form/tree/master/dist

I have selected inline editor option here.

![Configure Cloud function](https://thepracticaldev.s3.amazonaws.com/i/5lpzekvbuedwk187mgjb.png)


### Step 4: Add code to editor
Open the repository https://github.com/bansal-io/serverless-contact-form
Copy the code of `index.js` and `package.json` files and paste it to respective code editor tabs.

In the field Functions, to execute type onSubmit

![Import code](https://thepracticaldev.s3.amazonaws.com/i/33xfn30rsjq3kue0jd7c.png)


### Step 5: Set Environment Variables
All the Environment Variables Related to SMTP are required. The rest of the variables are optional. Check the configuration details https://github.com/bansal-io/serverless-contact-form/#configure
Click on ‘*Create*’ button and your function is ready.

![Set Environment variables](https://thepracticaldev.s3.amazonaws.com/i/90lgrwitsi4zugulehhq.png)

> Note: Instead of setting environment variables, you can also change the config values in `index.js` file.


## Get http endpoint
Once function is deployed, click on the function name (contact-form) then Trigger tab to find the url.

*Your url will look like this.*

https://YOUR_REGION-YOUR_PROJECT_ID.cloudfunctions.net/FUNCTION_NAME

Now you can set this url in action attribute in your HTML form

Here is a working example of contact form with Google cloud function https://serverless-contact-form.netlify.com/

> Note: This code allows to accept requests from any domain. To restrict this with your domain only, you can also change ‘Access-Control-Allow-Origin’ value from ‘*’ to ‘https://your-website.com’.