Use Notion as Backend for your NextJS App

Use Notion as Backend for your NextJS App

A few months back when Notion officialized their new API, I meant to try it out, which allows you to access the information stored in notion pages...

ยท

5 min read

When I was checking Notion for the first time in early 2021, I wasn't really amazed by it and I couldn't understand why everyone was such a fan of using that tool , where you could think, write, and plan

Thinking about that now, I think it just didn't click from the beginning, but lately I realized that I was using it for more and more stuff. What am I using it for?

  • Need to remember to do certain stuff, like life-admin? Create a todo-database!
  • Need to structure your work a bit? Create a todo-database!
  • Have a great startup idea? Write it down, and remember it (a few months) later, when you're ready to implement it ๐Ÿš€
  • Do you find a website you want to bookmark? Create a database

But now enough of general information about how I am using Notion.

A few months back when Notion officialized their brandnew API in May 2021, I meant to try out their API, which allows you to access the information stored in databases and pages easily:

image.png

Project

The result of using the Notion API resulted in the following project: www.nomadlinks.io:

image.png

Over the last couple months I was really interested in trying to pursue a location independent life, so I was reading/investigating a lot about digital nomads, travelling, coworking and colivings. But most of the time I thought that it's interesting, but maybe for later.

Instead of trying to put everything in my brain ๐Ÿง  and probably just forget it later on I decided to store in a Notion database and adding certain tags to it, in order to find it quicker when I would actually need the information later on:

image.png

Hint: Did you know there's "Save to Notion"- Chrome Extension that allows you to save bookmarks easily?

Instead of just having a Notion database I decided to use this, as en example of how to use the Notion API by using a NextJS project with tailwindcss added. Like described on the Tailwind CSS page I created a new project with the following command

npx create-next-app -e with-tailwindcss nomadlinks

Setup NextJS' ISR

The next Step was to create a file called /lib/notion.js where I would actually query all the content for the data that was needed for NextJS Incremental Static Regeneration (ISR). But let's quickly look how the getStaticProps looks like:

export const getStaticProps = async () => {

  const databaseId = process.env.NOTION_DATABASE
  const { results: links, hasMore } = await getDatabase(databaseId);

  return {
    props: {
      links,
      hasMore
    },
    revalidate: 1,
  }
}

(Btw, here's a guide about ISR from Lee Robinson)

As you can see here we just need specify the Notion database by reading the Environment-Variable.

But how can you get your own?

Easy, navigate to your Notion database. In the adress bar, you then would see a link that's like that: https://www.notion.so/yourNotionDatabaseId?v=yourVersionNumber

Now, copy the Database Identifier to your .env file and you're ready to go. Well, not quite.

For me understanding how to generate the Notion Token, or realize that you need to give access to the token to certain pages before you can acess them ๐Ÿ˜ฌ

Get the Token

The steps to get the token are the following:

  1. Login to your Notion Workspace
  2. Access the Integrations
  3. Create a new Integration
  4. Select a workspace
  5. Copy the Internal Integration Token and leave everything how it is
  6. Save changes
  7. Save the copied token to your .env file

Before requests with your brandnew token will actually return data from your pages or databases

If you want to play around a bit with your token and any database or pages, you can use Notion's public postman workspace:

image.png

Get the Data

Querying the data from Notion is actually quite straightforward and doesn't need much lines of code:

import { Client } from "@notionhq/client"

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

const getDatabase = async (databaseId) => {
    const response = await notion.databases.query({
        database_id: databaseId,
    });
    return parseResults(response)
}

export { getDatabase }

Parsing the returned data was actually a bit more tricky and needed some time and debugging for to actually get it working.

image.png

As currently I am using the following properties in my database, I had to parse them all of the HTTP response (and can be done much better, but it's working for now):

const parseProperties = (properties) => {
    const { URL, Name, Tags, Image, Published } = properties
    const url = URL ? URL.url : ""
    const name = Name.title[0] ? Name.title[0].plain_text : ""
    const tags = Tags.multi_select && Tags.multi_select.map((tag) => tag.name)
    const image = Image.files.length > 0 ? Image.files[0].file.url : ""
    const published = Published.checkbox

    return { url, name, tags, image, published }

}

const parseResults = (response) => {
    const { has_more: hasMore, results: receivedResults } = response
    const results = receivedResults.map(item => {
        const { 
            id, 
            properties, 
            created_time: createdTime, 
            last_edited_time: editedTime 
         } = item
         const { 
              url, 
              name, 
              tags, 
              image, published } = 
              parseProperties(properties)

        return {
            id,
            createdTime,
            editedTime,
            name,
            url,
            tags,
            image,
            published
        }

    }).filter(item => item.name && item.published)
    return { hasMore, results }
}

Feel free to headover to the Github repository to see the full code.

To finish, here are a couple of resource if you're intested in the Notion API:

Gracias ๐Ÿ™

Thanks for taking 5 minutes of your precious time - and reading this few bytes about how I played around with the Notion API. Feel free to connect on Twitter with me

ย