Гид по технологиям

Интеграция Notion с Express и React

6 min read Разработка Обновлено 05 Jan 2026
Notion + Express + React: интеграция и CMS
Notion + Express + React: интеграция и CMS

Компьютеры с кодом на столе

Зачем использовать Notion как CMS

Notion предоставляет гибкую систему баз данных, удобный веб-интерфейс и API для автоматизации. Это делает Notion удобным вариантом для приложений, которым нужна простая CMS без развёртывания собственной панели управления. Кратко:

  • Подходит для быстрых MVP и внутренних инструментов.
  • Упрощает редактирование контента для нетехнических сотрудников.
  • Позволяет хранить структуры данных и извлекать их через API.

Определение: Notion API — HTTP API и официальная библиотека клиента, которая позволяет читать и записывать страницы и базы данных Notion программно.

Важно: Notion хорош для контента и управления, но не заменяет полнофункциональные headless CMS для высоконагруженных публичных сайтов без дополнительных оптимизаций.

Быстрый обзор архитектуры

  • Клиент (React) — форма и отображение данных, отправляет POST/GET на ваш сервер.
  • Сервер (Express) — хранит токен интеграции, валидацию, взаимодействует с Notion через клиентскую библиотеку @notionhq/client.
  • Notion Database — место хранения строк (страниц) с полями, такими как Fullname, CompanyRole, Location.

Страница настроек создания интеграции в Notion

1. Создание интеграции Notion (Internal Integration)

  1. Перейдите на страницу интеграций Notion, войдите в свой аккаунт и нажмите New Integration.
  2. Дайте имя интеграции, выберите права доступа (Capabilities) и нажмите Submit.
  3. Скопируйте секретный Internal Integration Token и сохраните его в безопасном месте.

Настройки возможностей интеграции Notion

Совет: выдавайте интеграции минимально необходимые права (Least Privilege). Если интеграция только пишет в конкретную базу — не давайте глобальных прав на чтение всех страниц.

2. Создание базы данных Notion и подключение интеграции

  1. В рабочем пространстве Notion нажмите New Page и создайте базу данных (Table).
  2. Настройте столбцы (поля) таблицы: Fullname (Title), CompanyRole (Rich Text), Location (Rich Text).

Демонстрационная база пользователей в Notion

  1. Откройте базу как полноэкранную страницу, чтобы увидеть URL и найти database_id.

Кнопка Open as Full Page

  1. Database ID — строка в URL между последним слэшем и вопросительным знаком.

ID базы данных в URL страницы Notion

  1. Подключите интеграцию к базе: в правом верхнем углу нажмите три точки, затем Add connections и выберите интеграцию.

Добавление подключения интеграции к базе данных

Важно: без подключения база не будет доступна интеграции даже при наличии токена.

3. Создание Express-сервера

В корне проекта создайте папку сервера и установите зависимости:

npm install @notionhq/client cors body-parser dotenv

Создайте .env в корне сервера и добавьте:

NOTION_INTEGRATION_TOKEN = 'your Integration secret token'  
NOTION_DATABASE_ID = 'database ID'

Откройте index.js и добавьте следующий код (пример рабочей реализации):

const express = require('express');  
const {Client} = require('@notionhq/client');  
const cors = require('cors');  
const bodyParser = require('body-parser');  
const jsonParser = bodyParser.json();  
const port = process.env.PORT || 8000;  
require('dotenv').config();  
  
const app = express();  
app.use(cors());  
  
const authToken = process.env.NOTION_INTEGRATION_TOKEN;  
const notionDbID = process.env.NOTION_DATABASE_ID;  
const notion = new Client ({auth: authToken});  
  
app.post('/NotionAPIPost', jsonParser, async(req, res) => {  
    const {Fullname, CompanyRole, Location} = req.body;  
  
    try {   
        const response = await notion.pages.create({  
            parent: {  
                database_id: notionDbID,  
            },  
            properties: {  
                Fullname: {  
                    title: [  
                        {  
                            text: {  
                                content: Fullname  
                            },  
                        },  
                    ],  
                },  
                CompanyRole: {  
                    rich_text: [  
                        {  
                            text: {  
                                content: CompanyRole  
                            },  
                        },  
                    ],  
                },  
                Location: {  
                    rich_text: [  
                        {  
                            text: {  
                                content: Location  
                            },  
                        },  
                    ],  
                },  
            },  
        });  
  
        res.send(response);  
        console.log("success");  
    } catch (error) {  
        console.log(error);  
    }  
});  
  
app.get('/NotionAPIGet', async(req, res) => {  
    try {   
        const response = await notion.databases.query({  
            database_id: notionDbID,   
            sorts: [  
                {  
                    timestamp: 'created_time',  
                    direction: 'descending',  
                },  
            ]  
        });  
  
        res.send(response);  
        const {results} = response;  
        console.log("success");  
    } catch (error) {  
        console.log(error);  
    }  
});  
  
app.listen(port, () => {  
    console.log('server listening on port 8000!');  
});

Что делает серверный код

  • Инициализирует клиент Notion с токеном интеграции.
  • POST /NotionAPIPost: создаёт новую страницу в базе данных с указанными свойствами.
  • GET /NotionAPIGet: запрашивает записи из базы данных и сортирует их по времени создания.

Рекомендации по улучшению:

  • Добавьте валидацию входных данных и возврат понятных кодов ошибок клиенту.
  • Обрабатывайте исключения и возвращайте HTTP-статусы (400/401/500).
  • Логирование ошибок в централизованный сервис (Sentry, Logstash).
  • Реализуйте ограничение частоты запросов (rate limiting) и повторную попытку (retry) при сетевых ошибках.

4. Создание React-клиента

В корне проекта создайте React-приложение и установите Axios:

npm install axios

Замените содержимое src/App.js этим кодом:

import React, { useState} from 'react';  
import Axios from 'axios';  
  
function App() {  
  const [name, setName] = useState("");  
  const [role, setRole] = useState("");  
  const [location, setLocation] = useState("");  
  const [APIData, setAPIData] = useState([]);  
  
  const handleSubmit = (e) => {  
    e.preventDefault();  
  
    Axios.post('http://localhost:8000/NotionAPIPost', {  
      Fullname: name,  
      CompanyRole:role,  
      Location:location  
    }).catch(error => {  
      console.log(error);  
    });  
  
    Axios.get('http://localhost:8000/NotionAPIGet')  
      .then(response => {  
        setAPIData(response.data.results);  
        console.log(response.data.results);  
      }).catch(error => {     
        console.log(error);  
      });   
  };  
  
  return (  
    
      
        
          
            

First Name

             {setName(e.target.value)}}             />             

Company Role

             {setRole(e.target.value)}}             />             

Company Role

             {setLocation(e.target.value)}}             />                        
        
        
          

API DATA

          {             APIData.map((data) => {               return (                 
                   

Name: {data.properties.Fullname.title[0].plain_text}

                   

Role: {data.properties.CompanyRole.rich_text[0].plain_text}

                   

Location: {data.properties.Location.rich_text[0].plain_text}

               
              )            })           }         
      
    
  ); } export default App;

Пояснение:

  • Компонент использует useState для управления формой.
  • При отправке формы сначала POST, затем GET для обновления списка.
  • В реальном приложении лучше держать порядок: дождаться ответа POST, затем запросить свежие данные.

Практические рекомендации и распространённые ошибки

  1. Неправильный database_id: убеждайтесь, что вы копируете ID без лишних символов.
  2. Токен интеграции не действует, если интеграция не подключена к базе.
  3. Ошибки CORS: позаботьтесь, чтобы сервер выставлял корректные заголовки Access-Control-Allow-Origin.
  4. Обработка пустых полей в ответах Notion: rich_text и title могут быть пустыми массивами — проверяйте существование перед доступом.

Пример безопасного доступа:

const getPlainText = (prop) => {
  if (!prop) return '';
  if (prop.title && prop.title.length) return prop.title[0].plain_text || '';
  if (prop.rich_text && prop.rich_text.length) return prop.rich_text[0].plain_text || '';
  return '';
}

Безопасность и эксплуатация

  • Храните секреты в переменных окружения или в секретном хранилище (HashiCorp Vault, AWS Secrets Manager).
  • Ограничьте доступ к серверу и используйте HTTPS в продакшене.
  • Регулярно вращайте (rotate) интеграционные токены.
  • Логи не должны содержать секретные значения.
  • Применяйте CORS и CSRF-защиту.Важно контролировать права интеграции и давать минимально необходимые разрешения.

Критерии приёмки

  • Форма в React отправляет запрос и отвечает кодом 200 при успешной записи.
  • Запись появляется в базе Notion и отображается на клиенте после обновления.
  • Сервер возвращает понятные ошибки для неверного payload и для проблем авторизации.
  • Логи ошибок доступны в системе мониторинга и не содержат токена.

Тесты и кейсы приёма

  • Позитивный сценарий: отправить валидные данные → проверить появление записи в Notion.
  • Негативный сценарий: отправить пустые поля → сервер возвращает 400.
  • Сценарий отказа авторизации: неверный токен → 401 и понятный лог.
  • Интеграционный тест: end-to-end тест, который использует тестовую базу в Notion (изолированную).

Мероприятие при инциденте (Runbook)

  1. Симптом: пользователи не видят новые записи.
  2. Шаг 1: проверить логи сервера на ошибки 4xx/5xx.
  3. Шаг 2: проверить статус токена и подключение интеграции к базе в Notion.
  4. Шаг 3: выполнить тестовый запрос к Notion API с curl или Postman и проверить ответ.
  5. Шаг 4: при утечке токена — немедленно отозвать токен, сгенерировать новый и обновить переменные окружения.

Пример проверки curl:

curl -X GET "https://api.notion.com/v1/databases/{database_id}/query" \ 
  -H "Authorization: Bearer YOUR_TOKEN" \ 
  -H "Notion-Version: 2022-06-28"

(Проверьте актуальную версию заголовка Notion-Version в официальной документации.)

Карта принятия решений (Mermaid)

flowchart TD
  A[Нужно использовать Notion?] -->|Внутренний инструмент, быстрый MVP| B[Использовать Notion]
  A -->|Высокая нагрузка, сложная схема| C[Рассмотреть специализированный headless CMS]
  B --> D[Настроить интеграцию и базу]
  D --> E[Сервер на Express + клиент React]
  E --> F[Добавить безопасность и мониторинг]

Роли и чеклисты

  • Разработчик фронтенда:

    • Реализовать форму с валидацией.
    • Обработать ошибки API и состояния загрузки.
    • Тестировать рендер свойств Notion (проверять пустые массивы).
  • Разработчик бэкенда:

    • Безопасно хранить токены.
    • Валидировать входящие данные.
    • Логировать ошибки и ответы API.
  • DevOps:

    • Хранение секретов, HTTPS, мониторинг.
    • Настроить CI/CD, секреты в окружении.
  • Продукт/Контент-менеджер:

    • Настроить поля базы данных.
    • Описать правила ввода данных и права доступа.

Миграции и изменения схемы

  • Изменения структуры свойств (переименование поля) ломают существующий код — документируйте схему и вносите изменения поэтапно.
  • Для сложных миграций создайте скрипт, который читает старые страницы и создаёт новые с новой структурой.

Совместимость и ограничения

  • Notion API может иметь ограничения по скорости запросов — реализуйте backoff и retry.
  • Свойства типа rich_text или title могут иметь вложенные элементы — парсите аккуратно.
  • Для больших объёмов данных планируйте пагинацию при запросе баз данных.

Конфиденциальность и соответствие требованиям

  • Если вы храните персональные данные (ФИО, адрес, контакт), оцените требования местного законодательства по защите данных.
  • Для GDPR: документируйте правовые основания хранения и срок хранения, предоставьте возможность удаления данных по запросу.

Полезные сниппеты и чек-листы

  • Безопасный доступ к полю:
const safeGet = (obj, path, fallback = '') => {
  try { return path.split('.').reduce((o,k) => o[k], obj) || fallback } catch { return fallback }
}
  • Минимальный конфиг .env в продакшене: держите в CI/CD, не коммитьте в git.

Краткое резюме

Notion — удобный инструмент для быстрой CMS-реализации. Архитектура: React → Express → Notion. Следите за безопасностью токенов, валидацией данных и обработкой ошибок. Документируйте схему базы данных и имейте план миграции.

Важные шаги: создать интеграцию, получить database_id, подключить интеграцию к базе, реализовать серверный слой с @notionhq/client и безопасно хранить секреты.

Спасибо за чтение. Удачной интеграции!

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как настроить «Не беспокоить» на iPhone
iPhone

Как настроить «Не беспокоить» на iPhone

Управление проектами Unity через Unity Hub
Разработка игр

Управление проектами Unity через Unity Hub

Firefox OS: запуск приложений на Android
Мобильные

Firefox OS: запуск приложений на Android

Как включить аудиоописание на Peacock
Инструкции

Как включить аудиоописание на Peacock

Оптимизация SSD: AHCI, TRIM, прошивка
SSD

Оптимизация SSD: AHCI, TRIM, прошивка

Как сообщения душат отношения и что с этим делать
Отношения

Как сообщения душат отношения и что с этим делать