Інтеграція Notion API з веб-сайтом
Notion як headless CMS — нішева, але практична рішення для команд, які вже ведуть документацію в Notion. База даних Notion стає бекендом для блогу, документації або каталогу. Контент редагується в Notion, сайт отримує дані через офіційний API.
Notion API: робота з базами даних
import { Client, isFullPage } from '@notionhq/client';
const notion = new Client({ auth: process.env.NOTION_API_KEY });
// Отримання записів з бази даних
async function getBlogPosts(): Promise<BlogPost[]> {
const response = await notion.databases.query({
database_id: process.env.NOTION_BLOG_DB!,
filter: {
property: 'Published',
checkbox: { equals: true }
},
sorts: [{ property: 'Date', direction: 'descending' }],
});
return response.results
.filter(isFullPage)
.map(page => ({
id: page.id,
title: (page.properties.Title as any).title[0]?.plain_text ?? '',
slug: (page.properties.Slug as any).rich_text[0]?.plain_text ?? '',
date: (page.properties.Date as any).date?.start ?? '',
excerpt: (page.properties.Excerpt as any).rich_text[0]?.plain_text ?? '',
cover: page.cover?.type === 'external' ? page.cover.external.url : null,
tags: (page.properties.Tags as any).multi_select.map((t: any) => t.name),
}));
}
Отримання контенту сторінки
Notion зберігає контент як блоки. notion-to-md конвертує їх в Markdown:
import { NotionToMarkdown } from 'notion-to-md';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkHtml from 'remark-html';
const n2m = new NotionToMarkdown({ notionClient: notion });
async function getPageContent(pageId: string): Promise<string> {
const mdBlocks = await n2m.pageToMarkdown(pageId);
const mdString = n2m.toMarkdownString(mdBlocks);
const result = await unified()
.use(remarkParse)
.use(remarkHtml)
.process(mdString.parent);
return String(result);
}
ISR з on-demand revalidation
При змінах запису в Notion — Zapier або Make.com викликають webhook сайту, який інвалідує кеш конкретної сторінки:
// Next.js: on-demand revalidation
export async function POST(request: Request) {
const { page_id, slug } = await request.json();
await revalidatePath(`/blog/${slug}`);
await revalidatePath('/blog');
return Response.json({ revalidated: true });
}
Обмеження
- Rate limit: 3 запити на секунду — кешування обов'язкове
- Notion не підтримує нативні webhooks (тільки через Zapier/Make)
- Деякі блоки (бази даних усередину сторінок, синхронізовані блоки) API не повертає
Графік
Сайт з Notion як CMS (список + деталь сторінок): 3–5 робочих днів.







