Интеграция CMS Contentful для управления контентом

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Интеграция CMS Contentful для управления контентом
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Интеграция CMS Contentful для управления контентом

Contentful — облачная headless CMS с сильной экосистемой SDK, развитым API и встроенной мультиязычностью. Контент хранится в инфраструктуре Contentful, доступ — через Delivery API (публичный, кешированный) и Management API (запись, приватный).

Структура Contentful

  • Space — рабочее пространство, аналог проекта
  • Environment — среды внутри Space (master, staging, sandbox)
  • Content Type — схема типа записи: поля, валидации
  • Entry — конкретная запись определённого Content Type
  • Asset — медиафайл (изображение, видео, PDF)

Каждый Entry и Asset имеет уникальный ID, не зависящий от языка. Локализованные поля хранятся как словарь {locale: value} внутри одной записи.

Создание Content Type через API

import Contentful from 'contentful-management';

const client = Contentful.createClient({ accessToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN });
const space = await client.getSpace(process.env.CONTENTFUL_SPACE_ID);
const env = await space.getEnvironment('master');

const contentType = await env.createContentTypeWithId('article', {
    name: 'Article',
    displayField: 'title',
    fields: [
        { id: 'title',       name: 'Title',        type: 'Symbol',   required: true, localized: true },
        { id: 'slug',        name: 'Slug',         type: 'Symbol',   required: true, localized: false },
        { id: 'body',        name: 'Body',         type: 'RichText', required: false, localized: true },
        { id: 'cover',       name: 'Cover Image',  type: 'Link', linkType: 'Asset' },
        { id: 'author',      name: 'Author',       type: 'Link', linkType: 'Entry',
          validations: [{ linkContentType: ['author'] }] },
        { id: 'tags',        name: 'Tags',         type: 'Array',    items: { type: 'Symbol' } },
        { id: 'publishedAt', name: 'Published At', type: 'Date' },
    ],
});

await contentType.publish();

Delivery API (чтение контента)

import { createClient } from 'contentful';

const client = createClient({
    space:        process.env.CONTENTFUL_SPACE_ID!,
    accessToken:  process.env.CONTENTFUL_ACCESS_TOKEN!,  // Delivery API token
    environment:  'master',
});

// Получить список статей
const response = await client.getEntries<ArticleFields>({
    content_type: 'article',
    'fields.publishedAt[lte]': new Date().toISOString(),
    order: ['-fields.publishedAt'],
    limit: 10,
    locale: 'ru',
    include: 2,  // глубина populate (автор, обложка)
});

response.items.forEach(entry => {
    console.log(entry.fields.title);           // string
    console.log(entry.fields.cover?.fields);   // Asset fields
});

// Конкретная запись по slug
const entries = await client.getEntries({
    content_type: 'article',
    'fields.slug': 'my-article',
    locale: 'ru',
    limit: 1,
});
const article = entries.items[0];

TypeScript-типы из Content Types

npx @contentful/cli@latest content-type export \
    --space-id $CONTENTFUL_SPACE_ID \
    --output-file src/types/contentful.d.ts

Или через cf-content-types-generator:

npx cf-content-types-generator -s $SPACE_ID -t $ACCESS_TOKEN -o src/types/

Rich Text рендеринг

Contentful Rich Text хранится как JSON AST, не HTML. Для рендеринга:

import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
import { BLOCKS, INLINES } from '@contentful/rich-text-types';

const options = {
    renderNode: {
        [BLOCKS.EMBEDDED_ASSET]: (node) => {
            const { url, title } = node.data.target.fields.file;
            return <img src={`https:${url}`} alt={title} />;
        },
        [INLINES.HYPERLINK]: (node, children) => (
            <a href={node.data.uri} target="_blank" rel="noopener noreferrer">
                {children}
            </a>
        ),
        [BLOCKS.EMBEDDED_ENTRY]: (node) => {
            const entry = node.data.target;
            if (entry.sys.contentType.sys.id === 'codeBlock') {
                return <pre><code>{entry.fields.code}</code></pre>;
            }
        },
    },
};

<div>{documentToReactComponents(article.fields.body, options)}</div>

Content Preview API

Для предпросмотра черновиков используется Preview API с отдельным токеном:

const previewClient = createClient({
    space:       process.env.CONTENTFUL_SPACE_ID!,
    accessToken: process.env.CONTENTFUL_PREVIEW_TOKEN!,  // Preview API token
    host:        'preview.contentful.com',               // не cdn.contentful.com
});

Webhooks для ISR

Space Settings → Webhooks → Add Webhook
Name: Next.js Revalidation
URL: https://example.com/api/revalidate
Events: Entry.publish, Entry.unpublish, Asset.publish
// app/api/revalidate/route.ts
export async function POST(req: Request) {
    const body = await req.json();
    const contentType = body.sys?.contentType?.sys?.id;

    if (contentType === 'article') {
        await revalidatePath('/blog');
        await revalidatePath(`/blog/${body.fields?.slug?.['en-US']}`);
    }

    return Response.json({ revalidated: true });
}

Мультиязычность

Contentful поддерживает локализацию на уровне полей. Поле localized: true в схеме → при запросе к API добавить locale=ru, locale=en.

// Получить запись для всех локалей одновременно
const entry = await client.getEntry(entryId, { locale: '*' });
// entry.fields.title = { 'ru': 'Заголовок', 'en': 'Title', 'de': 'Titel' }

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

Бесплатный тариф Contentful (Community): 1 Space, до 25 000 записей, 2 роли, 2 языка. Для production с командой и несколькими средами (staging + production) нужен платный тариф.

Альтернатива при бюджетных ограничениях: Directus (self-hosted) или Sanity (free tier щедрее).

Сроки

Настройка Space, Content Types, SDK, интеграция с Next.js, webhooks для ISR — 3–5 рабочих дней. Мультиязычность, Preview Mode, CI/CD с миграциями схемы — +2–3 дня.