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

Интеграция 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
Автор
Редакция

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

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро