Интеграция 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 рабочих дней.







