Form Handling for Jamstack Sites Using Cloudflare Workers

In this tutorial, you’ll learn how to build a form-handling service for your Jamstack website or single page application (SPA) using Cloudlflare Workers.

With Jamstack technology, HTML code is rendered at build time and then deployed to edge servers. This allows very fast load times for end users. In addition, businesses benefit by paying much significantly lower hosting fees.

One issue with Jamstack technology is how to deal with site features that can only be implemented with server-side technologies. For example, form handling is relatively easy if you have access to a server-side technology like PHP, where you can just use mail(<to>, <from>, <message>) to collect and send mail data.

Of course, Jamstack sites aren’t left out in the cold. You can run back-end applications on a Jamstack site using serverless computing. But you’ll need to implement a microservice architecture in your back-end development. Serverless computing requires that you build your logic into loosely coupled, independently deployable services.

Serverless computing can be a lot more cost-effective than renting private servers often needed for running back-end apps. An added bonus of serverless computing is that you can start to create more complicated workflows using further services (such as using services like Airtable to store form data).

For this tutorial, you’ll learn how to build and deploy a form-handling service for a React front-end SPA. Technically, any front-end framework will do. We’ll use Cloudflare Workers to develop our serverless function. Before we start working on the code, let’s first have an overview of why we’ll be using this technology stack. (If you’d rather get to the hands-on part straight away, jump to the project section.)

About Third-party Form-handling Services

There’s already a good number of API form-handling services that provides the features we need. These include:

  • FormSpree
  • Getform
  • FormData
  • Netlify Forms

The features they offer include:

  • email notification
  • spam blockage
  • integration with other services through Zapier
  • dashboard data view
  • file upload and storage
  • CSV export

That’s a lot of value that frees you from having to build such a service yourself. Also, it only takes about five minutes or less to integrate the service with an existing web application. Most platforms offer a free plan that gives you about 50 to 100 free submissions per month with about 100MB of file storage.

Paid plans start from $9 a month with 1,000 submissions and 1GB of file upload storage. If you’re using the service to capture leads, the price is quite fair. However, if you’re using it for a different purpose — such as collecting massive amounts field data — it can get expensive quickly.

This is where building your own form-handling service can be advantageous. There are several benefits, which include:

  • lower cost per form submission
  • implementation of custom security policies
  • unlimited integrations with other services
  • reduction in latency, since you have control of how and where the service is hosted
  • ability to add new features not currently offered by a form-handling provider

In regards to lower cost per submission, transaction email service providers such as SendGrid and Mailgun currently have an offer that allows you to send between 3,000 to 5,000 emails per month for free. The former’s offer is permanently free, while the latter’s offer only lasts for three months.

This, of course, is already too much email for anyone’s inbox. You’d probably want to send form data straight to your database or an application service designed to handle that data. If that’s the case, you’ll probably pay less than 10 dollars per a million submissions.

This pricing I’ve estimated is based on combined average pricing for major serverless computing and serverless database offerings. If you need file storage, you can get 250 Gigabytes of Linode Object Storage for $5 per month. You actually get so much more value when you spend the time to build the service yourself.

I hope those are enough reasons. If not, then learn to build just for the fun of it. You can apply the knowledge gained in other areas. In the next section, we’ll look into why we chose to build our own service with Cloudflare Workers.

About Cloudflare Workers

The first serverless computing platform to be introduced was Google App Engine, which was launched in 2008. However, the first commercially successful serverless offering was AWS Lambda, which was introduced by Amazon in 2014. Later, in 2016, Google introduced a second serverless offering known as Google Cloud Functions. IBM Cloud Functions and Azure Functions followed soon after.

While all these services provide the benefits of running back-end code at a significantly lower cost, most do suffer from a problem known as cold start. This is where an idle container hosting your function takes anywhere from 1 to 10+ seconds to respond to a request. There are many workarounds that have been documented to improve the situation, but not to solve it entirely.

Cloudflare Workers is the latest entry into the serverless computing market. The company has solved the cold start problem where idle serverless functions experience 0 millisecond boot time to respond to requests. They’ve achieved this by leveraging V8 runtime to execute serverless functions instead of running them in a Node.js environment. This guide explains more on how it works.

In addition, Cloudflare is an Edge computing platform. This basically means code is executed on servers nearest to end users. This greatly reduces network latency even further, and makes your application response instant.

Hopefully I’ve now convinced you that Cloudlflare Workers is the way to go. So let’s start building.

About the Project

The source code for the completed projects are included in the following links:

  • Cloudflare form UI: React single page application
  • Cloudflare form service: Cloudflare Workers application

We’ll go through building the Workers application step by step in this tutorial. Then we’ll download and configure the completed SPA (linked above) to connect to our completed Workers project.

We won’t be building the UI. We’ll deploy the application and test it with the Workers application that we’re going to build. The following section describes all the prerequisites needed to follow along with the tutorial.


This tutorial is intended for intermediate to advanced Node.js developers. I’ll assume you’re familiar with ES6+ notation and REST APIs. You’ll need the following setup in your development environment:

  • Node.js
  • Visual Studio Code
  • the VS Code REST Client extension

The REST Client extension is a more convenient tool for testing REST interfaces as opposed to using external applications.

Accounts Setup

In this section, we’ll set up all the service accounts we need to build our email-handling worker. Take note of all the API tokens and other IDs that we’ll use later on in the development process.

1. Custom Domain

In order to follow along this tutorial, it’s highly recommended that you have access to a custom domain and an email address using that domain. However, you can manage to get the code working using a sandbox domain and the free subdomain that Cloudflare gives you when you sign up. Do note that credit card information is required when setting up a custom domain on Mailgun.

Having a custom domain will allow you to:

  • deploy your Cloudflare projects on a custom domain
  • gain access to your deployed Workers logs in real time
  • send authentic emails that won’t end up in the spam box

If you don’t have access to a custom domain, I strongly suggest you purchase a new domain from FastComet. The reason I recommend them is because they’ll give you a free Lite Email package which you can use to set up your custom domain email address. Most providers will charge you extra for email hosting.

In the next section, we’ll set up a Mailgun account.

2. Mailgun Setup

Mailgun is an Email API service that allows developers integrate email functionality into their apps via APIs. We’ll use their REST API interface to send and email from our Workers application to a recipient. Basically this means we only need to use Fetch or Axios to send an email. Use the following guide to set up your Mailgun account:

  1. Head over to the sign up page and create a new account using the free plan.
  2. Verify your account using an email address and an SMS code sent to your phone.
  3. On Mailgun’s dashboard, go to Sending > Domains and you’ll find a sandbox domain has been created for you. This is a free domain provided for you to test the sending of emails.
  4. With a sandbox domain, you’re only allowed to send an email to an authorized recipient. On the current dashboard’s right sidebar, you’ll find a form where you can provide the email address of a recipient. Add one now. This will be the email address that will receive the emails sent from the Workers application that we’ll be building.
  5. An email will be sent to the authorized recipient’s inbox. Click confirm to complete step 4.
  6. On the sandbox’s Overview page, click on API > Select button.
  7. Next, select the curl tab. Take note of your API Key and the API base URL.
  8. Send a test email using the cURL command provided for the sandboxed domain. Ensure that you replace the relevant fields with your API tokens and your authorized email recipient.

sandbox sending domain setup

Here’s a quick example of how you can send yours:

curl -s --user 'api:key-0303d350c68aa534560ed0838bca66e' -F from='John Doe <>' -F -F subject='Hello' -F text='Message sent using Mailgun service' 

If successful, you should receive output like that shown below:

{ "id": "<>", "message": "Queued. Thank you." } 

You should also receive an email either on your authorized recipient’s inbox or spam box. If this happens, you’ve successfully set up your Mailgun account.

If you’d like to use a custom domain as your sending domain, do note that credit card information is required. You can follow the instructions here to learn how to set that one up. Using a custom domain allows you to unlock sending limits, and also to have your email source validated such that they’ll always end up on users’ inbox and not the spam box.

At the end of this section, you should have access to the following:

  • an API KEY: for example, api:key-0303d350c68aa534560ed0838bca66e
  • an API BASE URL: for example,
  • a FROM_EMAIL_ADDRESS: use any Gmail address or a custom domain address that you ‘ve registered with Mailgun
  • a TO_EMAIL_ADDRESS: an authorized recipient

Do note that the API key is also found under Settings > API Keys > Private API key.

3. Cloudflare Workers Setup

To get started, simply sign up for a Cloudflare Workers account. Follow the instructions provided:

  1. enter email address and password
  2. choose a subdomain for your account
  3. choose a plan: select free
  4. verify your email address

Next, install and configure Wrangler CLI, which you’ll use to develop Workers projects:

# Install wrangler CLI globally npm install -g @cloudflare/wrangler # Confirm version wrangler --version # Login to your Workers account wrangler login # Confirm login status wrangler whoami 

In case the login command fails for you, there are a few workarounds which have been documented on this GitHub issue. These are the steps that worked for my machine:

  1. Execute wrangler login again in the terminal.

  2. As soon as the Authorize page loads, Press F12 to open the Inspector, then switch it to Network tab.

  3. Click on the Authorize Wrangler button and wait till says “Wrangler is now authorized”.

  4. Under the Network tab within the Inspector console, locate the last POST request. Click on it to highlight it.

  5. A Request tab should appear. Click on it to access it. There should be some JSON data. The property “key” is the API token. Copy it.


  6. Go back to the terminal and use ctrl + c to cancel the last command. Execute the command wrangler config. You’ll be asked to enter your API token. Paste the key you just copied, then press enter. It should return a “Successfully configured” message.

  7. Confirm authentication was successful by executing wrangler whoami.

In the next subsection, we’ll look at how to add a custom domain to your Cloudflare account. If you don’t have one, simply skip to the “Project Development” section, where we can continue without one.

Continue reading Form Handling for Jamstack Sites Using Cloudflare Workers on SitePoint.

Similar Posts