Notion APIとNext.jsで簡単な日記アプリを作る(App directory、RSC)
はじめに
勉強用にNotion APIとNext.jsのApp Directory、RSCを用いて簡単なプロジェクトを作成しました。間違った認識等ありましたら、ご指摘いただけるとありがたいです。
ディレクトリ構成
.vscode/
node_modules
public/
src/
app/
├─ components/
│ ├─ Header/
│ │ ├─ Header.tsx
├─ favicon.ico
├─ globals.css
├─ layout.tsx
├─ page.tsx
.env
.gitignore
next-env.d.ts
next.config.js
package.json
postcss.config.js
README.md
tailwind.config.ts
tsconfig.json
yarn.lock
Notionの設定
integrationのページで「new integration」を押下し、新しくintegrationを作成する。
名前やworkspaceの指定など必要事項を記入します。
今回はNotionのデータベースから読み込む作業だけになるので、「capabilities」の項目は「read content」にします。
記入後のページで「internal integration token」が出るのでコピーして保管しておきます。
次にnotionにデータベースを作成していきます。
新しいページを作成します。その際にTableの項目を選択します。
今回は作成したテーブルのタイトルを「Title」「Content」にし、どちらもテキスト型にしています。
いくつかデータを入力しておきます。
3点メニューの「Add connection」から現在使用しているデータベースを指定し、共有を有効にします。
database idはデータベースのurlの〜notion.so/
のあとから?v=〜
までの32桁の値になります。こちらも後程使用するので保管しておきます。
Next.jsのプロジェクト作成
yarn create next-app
でNext.jsのプロジェクトを作成します。
Notion SDK for JavaScriptの導入
yarn add @notionhq/client
を実行します。
.envファイルを作成し、保管しておいた「internal integration token」と「database id」を記入します。
NOTION_TOKEN="secret_your_integration-token"
NOTION_DATABASE_ID="your_database_id"
page.tsx
async function getData() {
const notion = new Client({ auth: process.env.NOTION_TOKEN})
const data = await notion.databases.query({ database_id: process.env.NOTION_DATABASE_ID || '' })
const notionList = data.results.map((_: any) => _.properties).map((_) => {
return {
title: _.title.title[0]?.plain_text,
description: _.description.rich_text[0]?.plain_text,
}
})
return notionList
}
RSCを使用しているので上記の関数内に処理を記述していきます。
次にnotion clientの初期化を行います。queryを使用しデータベースから値を取得します。
この際、型のエラーが発生するので || ''
こちらの記述を行います。
データベースからの値を利用しやすいように加工した後、notionListを返すようにします。
getData関数を利用してブラウザ表示していきます。
import { Client } from "@notionhq/client"
export default async function Page() {
const list = await getData()
return (
<div className="pl-[20px] mt-[60px] w-full max-w-[800px] mx-auto">
<h2 className="text-[28px] font-bold text-center mb-[32px]">Notion Database 日記</h2>
<ul className="mt-4 border p-[24px] rounded-md">
{list.map((item, index) => (
<li key={index} className="mb-[20px] border rounded-md p-[24px] bg-gray-900">
<div className="text-[16px] mb-[8px]"><span>Title:</span><p className="text-[20px] pt-1">{item.title}</p></div>
<div className="text-[16px]"><span>Content:</span><p className="text-[20px] pt-1">{item.description}</p></div>
</li>
))}
</ul>
</div>
)
}
// 先ほど記入した内容
async function getData() {
const notion = new Client({ auth: process.env.NOTION_TOKEN})
const data = await notion.databases.query({ database_id: process.env.NOTION_DATABASE_ID || '' })
const notionList = data.results.map((_: any) => _.properties).map((_) => {
return {
title: _.title.title[0]?.plain_text,
description: _.description.rich_text[0]?.plain_text,
}
})
return notionList
}
const list = await getData()
↑こちらの記述でtitle
とdescription
を含むnotionList
を取得できます。
最後にmapメソッドを使用して、データをループ表示させて完成となります。
Discussion