嗨大家~ 像昨天文章裡提的,這專案會採用 Notion 來當 CMS (包含資料庫),意思是部落格文章的新增編輯刪除都會發生在 Notion 裡。所以,這專案需要可以讀取 Notion database 的資料。今天就是來串 Notion SDK 讀取 DB 資料喔!開始之前有些步驟需要完成才能拿到 Notion 的讀取權限喔,請大家看這篇。
這專案會用到 Notion SDK,所以需要安裝 SDK,不過如果你們想要用 Notion API 也可以喔!:
npm install @notionhq/client
# or
yarn add @notionhq/client
裝完之後我們需要初始化 Client:
import { Client } from "@notionhq/client";
// 初始化 Client
const notion = new Client({
auth: process.env.NOTION_TOKEN, // Notion 的 secret token
});
因為我們要做的是部落格,所以這次不是用 Notion Page,而是用 Notion Database。Database 裡有很多 Pages,所以 Database 就是我們的部落格資料庫,然後 Page 是我們每篇部落格文章的內容。Notion API 有提供很多 endpoints,其中一個是取得該 database 裡的 pages:
export const queryDatabase = async (params) => {
const databaseId = process.env.NOTION_DATABASE_ID;
if (!databaseId) {
throw new Error("Required: Notion database ID.");
}
// 讀取資料庫裡的 pages
const response = await notion.databases.query({
database_id: databaseId,
filter: params?.filter,
sorts: params?.sorts,
});
return response;
};
在這裡用的是 notion.databases.query
而不是 notion.databases.retrieve
,retrieve
這 API 是來讀取該 database 的 properties,而 query
是來讀取 database 裡的 pages,我們也可以加 filter
和 sorts
做文章的過濾和排序。
{
"object": "list",
"results": [
{
"object": "page",
"id": "2e01e904-febd-43a0-ad02-8eedb903a82c",
"created_time": "2020-03-17T19:10:04.968Z",
"last_edited_time": "2020-03-17T21:49:37.913Z",
"parent": {
"type": "database_id",
"database_id": "897e5a76-ae52-4b48-9fdf-e71f5945d1af"
},
"archived": false,
"url": "https://www.notion.so/2e01e904febd43a0ad028eedb903a82c",
"properties": {
"Recipes": {
"id": "Ai`L",
"type": "relation",
"relation": [
{
"id": "796659b4-a5d9-4c64-a539-06ac5292779e"
},
]
},
...
}
}
],
"has_more": false,
"next_cursor": null
}
response
會包含 results
為 list of pages,還有 has_more
和 next_cursor
做 pagination 用的~
因為我們使用 Next.js,所以做部落格的話,應該要用 Next.js 的 dynamic routing!於是我們需要寫 getStaticPaths
:
export const getStaticPaths = async () => {
const blogs = await queryDatabase();
const paths = blogs.results.map((b) => ({
params: { id: b.id }, // Notion 的 Page ID 當路徑的 dynamic path
}));
return { paths, fallback: "blocking" };
};
把上面這段 code 放在 pages/blogs/[id].js
裡面,這樣我們會匹配到 /blogs/[id]
的動態路徑~
今天才讀取資料庫的文章,還沒把每篇文章的內容取出來,而抓完資料還要做多處理喔!現在還蠻流行把 Notion 當成 CMS 或是資料庫,把文章都寫在 Notion 裡,然後再用 API 取這些資料去顯示。今天的小功能還差很多很多,尤其是資料處理方面!XD 我發現第三方 library 大部分都不是用 Notion SDK 讀取資料,所以資料格式又不一樣Q 感覺要自己寫 Notion renderer 了 :o
大家想要看看之前的網站可以看這裡,或是直接到首頁~ 有任何問題可以問我,或是也可以討論未來要開發的 No-code 專案喔。
祝大家明天上班上課愉快!
晚安 <3