How to Add a Page to a Notion Database Using the Notion API

An Express Backend for a Save to Notion Chrome Extension

This article is the first article of a two-part article series on how to create a Chrome extension for saving and organizing bookmarks in a Notion database

The Problem

I have a bookmarks section on my personal website where I share a list of resources I find valuable, typically links to articles or books.

I save these resources in a Notion table featuring columns for the resource name, link, category, and date.

In my Next.js code, I use the Notion API to fetch these links and use ISR (incremental static rendering) to update them every 60 minutes.

Adding links to this list isn't as smooth as I'd like it to be. Currently, I have to go into Notion, open the table with the links, and manually enter all the details like the title, link, and tags.

It's not a terribly time-consuming process, but it could be much easier with a Chrome extension. Here's what I think the extension should do:

  1. Automatically extract the URL and title from the page.

  2. Allow me to add tags to the resource link.

  3. Provide a button to save the link to Notion with a single click.

So, how do we go about it? First, we need to create a Node.js server using Express that interacts with Notion and saves the link. Then, we'll build the Chrome extension that connects to this server.

In this article, we'll focus on setting up the Express backend.

Prerequisites

  1. Node.js and npm (Node package manager) installed in your development environment. You can download and install them from the Node.js website.

  2. Text Editor or IDE such as Visual Studio Code.

  3. Basic JavaScript Knowledge.

  4. Git (Version Control) installed. You can install it from the Git website.

  5. A Notion account

Create a Node.js Application

Step 1: Initialize a New Node.js Project

Open your terminal and create a directory where you want to create the Express application. Give it a name you prefer, I used save-to-notion. Navigate to the directory and run the following command to create a new Node.js project:

npm init -y

This command will create a Node.js project with the default values. Leave out the -y flag if you want to customize these values.

Step 2: Install Express

Install Express to your project using npm:

bashCopy codenpm install express --save

Step 3: Create an Express App

Create a JavaScript file named app.js . Add the following to this file to configure the application.

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;


// Start the server
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

In the above code, we're importing Express and initializing it. We are then starting the server on the specified port.

Step 4: Define Environment Variables

Since we're using environment variables, you will need to install and configure an NPM package called dotenv. Dotenv enables Node applications to access environment variables.

Run the command below to install it.

npm install dotenv

In app.js, add the following at the top to configure dotenv.

require("dotenv").config()

Next, create a .env file at the root of your directory and define the port number.

PORT=3000

Now, your application can access the port number.

Create a Notion Integration

A Notion integration lets you connect to a Notion workspace via the API.

There are two types of integrations - public and internal integrations.

A public integration is an integration designed for use by any Notion user with any Notion workspace while internal integrations are tied to a single workspace.

Since our application is for personal use, we'll create an internal integration following the steps below:

  • Visit the Notion integration dashboard.

  • Click + New integration.

  • Enter the integration name you prefer.

  • Click Secrets tab and copy the integration’s API secret.

You'll use this secret to authenticate requests to the Notion API so store it in the .env file.

NOTION_KEY="your-api-secret"

To use this integration to add data to a Notion database, you must grant explicit read/write permissions for this database.

First, you need to create a Notion database and name it Bookmarks. Give this table three columns, a name of type text, a link of type URL, and a category of type multi-select.

Then, follow these steps to grant the integration permission.

  • Click on the ... More menu in the top-right corner of the page.

  • Scroll down to + Add Connections.

  • Search for your integration by the name you gave it and select it.

  • Confirm the integration can access the page and all of its child pages.

You can now use the integration's API secret to access this database.

Add a Resource to Notion

In your project's directory, create a new file named notion.js. This is where you'll define functions that interact with the Notion API.

Step 1: Define the Notion Client

Notion provides a client named @notionhq/client for interacting with workspaces in JavaScript. Install it using npm.

npm install @notionhq/client

In notion.js, import the Notion client and initialize a new instance setting the auth option to the Notion API secret which you should have defined in your .env file:

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

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

Step 2: Add Pages to the Notion Database

To add a page (i.e. a new resource) to the Bookmarks database, we'll use notion.pages.create endpoint.

To add a page to the database, you'll need to specify the database ID. You can find this ID in the URL of your Notion database:

https://www.notion.so/{notion-workspace-name}/{databaseId}?v=fc187760d15f478c9d1eb634e98943e9

Add the retrieved database ID as a variable in your .env file:

DATABASE_ID="your-database-id"

Step 3: Create the addItem Function

In your notion.js file, create a new function named addItem that accepts name, url, and category as parameters. Remember these are the columns you created in the Notion database.

async function addItem(name, url,category) {
    try {
       return { error: null };
    }
    catch (error) {
        return { error: error.message };
    }

}

Right now, this function contains a try-catch block that returns an object containing an error value.

Modify the try block to make a request to Notion with the passed arguments.

await notion.pages.create({
  parent: { database_id: process.env.DATABASE_ID },
  properties: {
    Name: {
      title: [
        {
          text: {
            content: name,
          },
        },
      ],
    },
    link: {
      type: "url",
      url: link,
    },
    category: {
      multi_select: [
        {
          name: category,
        },
      ],
    },
  },
});

Note that we're passing the database id to the parent key, and describing the properties of the columns we are adding to the database.

Step 4: Create the add-url Endpoint

In your app.js file, define a POST route with the endpoint /add-url. This route will handle the addition of resources to Notion:


app.post("/add-url", async (req, res) => {
  try {
    const { name, link, category } = req.body;
    if(!name || !link || !category) {
        throw Error("Must include name, link, and category")
    }
    return res.json({ success: true, error: null });
  } catch (error) {
    return res.json({ success: false, error: error.message });
  }
});

In this endpoint, we are retrieving the name, link, and category from the request body. If any of these items are missing, we throw an error to exit the execution process early to avoid unnecessary requests to Notion

Step 5: Call the addItem Function

If the required data is present in the request body, call the addItem function from your notion.js file to add the resource to your Notion database:

    const response = await addItem(name, link, category);

If the response from this function contains an error, throw it.

    if (response.error) throw Error(response.error.message);

Altogether, the endpoint should look like this:

app.post("/add-url", async (req, res) => {
  try {
    const { name, link, category } = req.body;
    if(!name || !link || !category) {
        throw Error("Must include name, link, and category")
    }
    const response = await addItem(name, link, category);
    if (response.error) throw Error(response.error.message);
    return res.json({ success: true, error: null });
  } catch (error) {
    return res.json({ success: false, error: error.message });
  }
});

Test if this endpoint works using a REST client like Postman or use a Curl as shown below to make a POST request.

curl -X POST -H "Content-Type: application/json" -d '{"name": "Example Name", "link": "https://example.com", "category": "Example Category"}' http://localhost:3000/add-url

If successful, you should see a new entry in the Bookmarks database in your Notion workspace and the endpoint will respond with { "success": true, "error": null }.

Deploy the Application

There are several cloud providers you can deploy your application to. I used Back4app as it's free and quite straightforward to set up. Follow the instructions in their deploying Express applications guide to learn how to dockerize your app and deploy it.

Find the code for this article in GitHub.

In the next article, we'll talk about how you can use a Chrome extension to call the /add-url endpoint and add resources to the Bookmarks database.