Guides & Tutorials

Adding form submissions to Notion using Next.js and Netlify

Netlify forms are a great way to quickly and easily capture submissions to a form, and in this guide you’ll learn how to automatically add your form submissions to a Notion database in a Next.js app.

This guide assumes you already have a basic Next.js site set up, if you don’t, you can read more about this in the Next.js documentation.

Getting set up with Notion

The first step is getting everything you need to connect to your Notion database. To do this, you need to do to the Notion integrations page and create a new integration. Set up an internal integration as you don’t want it available to other Notion users. This will give you an Internal Integration Token, which you’ll use for submissions to the API.

Next up is sharing your desired database with the integration as when set up the integration doesn’t have access to any of your databases. To do this, go to the database you want the form submissions to go into and click the share menu in the top right corner, then click the text box and choose your integration from the list.

While you’re here, make a note of the random string of characters in your address bar that comes after the workspace name but before the question mark, this is your database ID.

    https://www.notion.so/workspacename/dd010e0a312d481e94dbf93d9d81094d?v=...
                                        |--------- Database ID --------|

Setting up the form

To start with, set up a normal HTML form as shown below.

<form name="contact" method="POST">
  <p>
    <label>
      Your Name: <input type="text" name="name" />
    </label>
  </p>
  <p>
    <label>
      Your Email: <input type="email" name="email" />
    </label>
  </p>
  <p>
    <button type="submit">Send</button>
  </p>
</form>

Only two adjustments are needed to get this set up with Netlify

  1. Add another property to the form element with data-netlify="true"
  2. Add a hidden input to your form that has value the same as name on the form, like this:
<input type="hidden" name="form-name" value="contact" />

Sending the data to Notion

In its current state, the form will work and will send data to Netlify, and you’ll be able to see it in the Dashboard of your project, but for this you’ll go a step further and add it to Notion too.

To do this, in the root level of your project create a folder named netlify, inside that one called functions and in there, put a file named submission-created.js. This is a special name that tells Netlify that this function should run when a submission is created.

The basic structure of a serverless function is like this

exports.handler = async function (event) {
  return {
    statusCode: 200
  }
}

This will just respond with the OK status code, but you can expand this for your functionality.

To get this all working, you need to install the package @notionhq/client, this is a library by Notion that makes working with their API easier. To install it, run:

npm install @notionhq/client

Now you can import this in submission-created.js like this:

const {Client} = require("@notionhq/client")

Then inside the function, declare a new client with the API token you got before:

const notion = new Client({ auth: process.env.NOTION_TOKEN });

Now you can use the event passed into the function to access the data submitted in the form.

const form = JSON.parse(event.body).payload.data

This will be an object with keys for each of the inputs you’ve described, so for example form.name will be whatever name has been submitted.

Next up is constructing the request to send to Notion, the first thing to do is tell Notion where to put the new record, and this is done with a parent key, with database ID inside:

const new_row = {
  parent: {
    database_id: process.env.DATABASE_ID,
  }
}

Then you can add whatever properties you have set up in the database, I’ve set the title column to “Name” and the email column to “Email”, but you can swap these out based on your preference

const new_row = {
  // Parent information
  properties: {
        Name: {
          title: [
            {
              text: {
                content: form.name,
              },
            },
          ],
        },
        Email: {
          email: form.email,
        },
    },
}

Each column type has a different way of specifying the data to be inserted, which you can find out on the Notion documentation. Here the title has the title type and email, the email type.

Then to create the page, you can use the Notion client you declared before and add pass it this object new_row

await notion.pages.create(new_row);

Local development

This bit isn’t essential, so skip on to the next section if you don’t want to develop locally.

First up, you need to install the Netlify CLI which allows for running forms, to do this run:

npm install netlify-cli -g

Then run netlify login to authenticate with Netlify and netlify init to initialize your project as a Netlify project.

Now, you can run the following command to set up the environment variables:

netlify env:set NOTION_TOKEN "yourNotionToken"
netlify env:set DATABASE_ID "yourDatabaseID"

Finally, running netlify dev will run your dev command set in package.json, but with the addition of all the Netlify features like environment variables and forms.

And doing this has also set you up with deployment, so you don’t need to worry about the next step!

Deployment

The final step is deploying your project, to do this sign up for a Netlify account if you don’t have one already, and link the Git repository you’re storing your project in. You’ll need to set two environment variables

  • NOTION_TOKEN - The internal integration token you got when setting up your Notion integration
  • DATABASE_ID - The ID of the database you want to insert your data in

Now you can go to the deployed website and fill out the form, you’ll be directed to a page telling you the form was submitted and if you go to your Notion database, you’ll see it in there too!

If you want to see the completed application, you can check out this GitHub repository.

Keep reading

Recent posts

How do the best dev and marketing teams work together?