Build a Jamstack subscription form with Netlify forms and Fauna - Part 2

Build a Jamstack subscription form with Netlify forms and Fauna - Part 2

Learn how to store the Netlify form data into a data store. We will understand how Netlify and Fauna work together in Jamstack way.


7 min read

Hey there ๐Ÿ‘‹! Welcome to part-2 of the tutorial. I hope you enjoyed part-1 in building a Jamstack form using Netlify Forms. This article will learn about storing the form data into the Fauna data store.

Here is the link to part-1 of the tutorial: Build a Jamstack subscription form with Netlify forms and Fauna - Part 1


So far, we have

  • Created a Subscription page using HTML and CSS. The highlight of the page was a form with a few input fields and a button.
  • Enabled the form to get parsed by the Netlify Forms for tracking and storing any submissions.
  • Understood the in-built Spam filter feature of Netlify Forms. We have also added extra protection by adding a honey-pot field.
  • Finally, enabled notifications such that we get e-mails when some users submit the form.

Exciting! Let us take it forward to integrate the Fauna to store the form data. Like before, you can refer to the source code from this repository,

Set up the Fauna Data Store

Fauna is a secured transactional database available to access using the cloud API and GraphQL. It is flexible and straightforward to get started with an easy learning curve. To get started, we have first to create a database. After that, we need to supply a schema file to create the collection and documents for data.

Create a Schema File

Create a folder with the name db at the root of the project folder. Create a schema file called schema.gql inside the db folder with the following content,

type Entry {
  fullName: String!
  email: String!
  frequency: String!

type Query {
  allEntries: [Entry!]!

It is a GraphQL file. We have defined a type, Entry, to map each of the form fields to the document properties in the database. We also define a query to return the list of entries that collect multiple form submissions.

Set up Database

If you don't have an account with Fauna, you can register from here. Login to the Fauna dashboard and create a new database. Provide a database name and save.

Create a Database

Click on the Security option at the left panel of your database configuration. Next, create the server key to access the database.

Create Security Token

Please select the Role as Server. In addition, you can optionally provide a key name.

Generate Key

Please take a backup of the generated key into a file. We will use it soon.

Server Key

Import the Schema

Let us now import the schema to create collections and documents in the database. First, click on the GraphQL option from the left menu of the database configuration page. It will open up a playground asking you to import schema. Next, click on the IMPORT SCHEMA button and upload the schema.gql file.

Import Schema

You will see a GraphQL code editor opens up to try out queries.

GraphQL Code Editor

Netlify Function to Store the Form Data

Now, we will write the code to store the subscription form data in the database. Create a file called .env at the root of the project folder with the following entry,


Please replace the <FAUNA_SERVER_ACCESS_KEY> with the key you have created while setting up the database.

You must mention the .env file entry in your project's .gitignore file. It will make sure there is no accidental commit and push of the .env file to the git repository.

Netlify Functions

Netlify Functions are serverless lambda functions managed by Netlify. We can trigger a Netlify Function when certain Netlify events occur. For example, when a form submission is verified, the event submission-created will occur, triggering a Netlify Function.

Create a folder functions at the root of the project folder. We will place all the Netlify function related code inside this folder. At this point, the project directory structure may look like this,

Functions Folder

Install node-fetch

Now, let's create a function connected to the Fauna database and interact with it using the GraphQL queries. To do that, we need to make XMLHTTPRequest(Ajax Calls) from the function. We will use a light-weight library called, node-fetch for this.

Using the command prompt, change the directory to the functions directory. Now use the following command to create the package.json file.

npm init -y

Now install node-fetch using this command,

yarn add node-fetch # or npm install node-fetch

Create the Function

Create a file named, submission-created.js under the functions directory with the following content,

const fetch = require("node-fetch");

exports.handler = async (event) => {
  const body = JSON.parse(event.body);
  const { email, fullName, frequency } =;

  const response = await fetch("", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.FAUNA_API_SECRET}`,
    body: JSON.stringify({
      query: `
        mutation($fullName: String!, $email: String!, $frequency: String!) {
            createEntry(data: { fullName: $fullName, email: $email, frequency: $frequency } {
      variables: {
    .then((res) => res.json())
    .catch((err) => console.error(err));

  return {
    statusCode: 302,
    headers: {
      Location: "success.html",
      "Cache-Control": "no-cache",
    body: JSON.stringify({}),

When a user submits the subscription form, Netlify will perform a form verification for spam. Once verified, it will trigger the submission-created event. Then, it will call the function automatically.

We get the form data using the body payload. Next, we make a POST call using the fetch method from node-fetch. Please notice, we use the GraphQL endpoint of Fauna and pass the required details in the query. Also, it is of type mutation and creates an Entry in the database.

Run the Function Locally

Netlify needs a particular build configuration file called netlify.toml to inform the location of the Netlify functions. Create the netlify.toml file at the root of the project folder with the following content.

  functions = "functions"

We can run the function locally before deploying to Netlify. To do that, please install the Netlify Command Line Interface(CLI) tool globally.

npm install netlify-cli -g

After installing, run the following command from the root of the project folder,

netlify dev

Now, you can access the application @localhost:8888. Fill up the form and submit it. You should see the form data entry into the Fauna database.

Data in fauna

Rest of the Configurations & Deploy

Let us now deploy the changes to Netlify. But, first, we need a do a few simple configuration changes to make this deployment work.

  • Add the following scripts section in the main package.json file(the one at the root level of the project folder)

    "scripts": {
      "functions": "cd functions && npm i && cd .."
  • Modify the netlify.toml file to include two more build configurations.

    command = "npm run functions"
    publish = "src"
    functions = "functions"

    Here we additionally specify the command to set up the function, set up a base publish directory.

  • Now, push all the code changes to your GitHub repository.

  • Browse to the Netlify Interface for the project we have created in part-1 of the tutorial.
  • Browse to the Build & deploy option and open up the Environment section.

    Environment in Netlify

  • Add the Fauna Secret Key as the environment variable.

    Add Fauna Environment

  • Trigger a Build.

That's it. We have deployed the form successfully with the Netlify function. Here is a quick demo of how the application works end-to-end.

In Summary

To Summarize,

  • Created a form using HTML, CSS, and Netlify Forms.
  • Enabled Spam protection using the honey-pot field.
  • Enabled e-mail notifications.
  • Set up a database with Fauna by uploading a GraphQL schema.
  • We have utilized the Netlify Function to write the submitted and verified data to the database.
  • Netlify Form submission triggers an event that enables us to trigger the function in turn.
  • Everything works serverless, including the function.

I hope you found the article insightful. If you enjoyed this article or found it helpful, let's connect. You can find me on Twitter(@tapasadhikary) sharing thoughts, tips, and code practices. Please hit the Subscribe button at the top of the page to get an email notification on my latest posts.

Did you find this article valuable?

Support Tapas Adhikary by becoming a sponsor. Any amount is appreciated!