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

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Интеграция CMS Payload CMS для управления контентом
Средняя
~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 Payload CMS для управления контентом

Payload — headless CMS на Node.js с открытым исходным кодом. Отличается от конкурентов тем, что сам является частью приложения: конфиг пишется на TypeScript и живёт в репозитории. Никаких внешних дашбордов, никакого vendor lock-in. Это не сервис — это библиотека, которую монтируешь в Express или Next.js.

Когда Payload имеет смысл

Продукт подходит, когда нужен полный контроль над схемой данных, кастомная аутентификация, или CMS нужно встроить в уже существующий backend. Payload не требует отдельного хостинга — он поднимается там же, где живёт API.

Не стоит использовать, если команда контент-менеджеров большая и привыкла к облачным CMS с гарантированным аптаймом — тогда Contentful или Prismic проще.

Структура проекта

my-project/
├── src/
│   ├── payload.config.ts   # главный конфиг
│   ├── collections/        # типы контента
│   │   ├── Posts.ts
│   │   ├── Users.ts
│   │   └── Media.ts
│   ├── globals/            # singleton-документы
│   │   └── SiteSettings.ts
│   └── server.ts

Конфигурация коллекции

// src/collections/Posts.ts
import { CollectionConfig } from 'payload/types'

const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    useAsTitle: 'title',
    defaultColumns: ['title', 'status', 'publishedAt'],
  },
  access: {
    read: ({ req: { user } }) => {
      if (user) return true
      return { status: { equals: 'published' } }
    },
    create: ({ req: { user } }) => Boolean(user?.roles?.includes('editor')),
    update: ({ req: { user } }) => Boolean(user?.roles?.includes('editor')),
  },
  versions: {
    drafts: { autosave: true },
    maxPerDoc: 20,
  },
  fields: [
    { name: 'title', type: 'text', required: true },
    { name: 'slug', type: 'text', unique: true, admin: { position: 'sidebar' } },
    {
      name: 'content',
      type: 'richText',
      editor: lexicalEditor({
        features: ({ defaultFeatures }) => [
          ...defaultFeatures,
          HTMLConverterFeature({}),
        ],
      }),
    },
    {
      name: 'featuredImage',
      type: 'upload',
      relationTo: 'media',
    },
    {
      name: 'status',
      type: 'select',
      options: ['draft', 'published'],
      defaultValue: 'draft',
      admin: { position: 'sidebar' },
    },
    {
      name: 'publishedAt',
      type: 'date',
      admin: { position: 'sidebar', date: { pickerAppearance: 'dayAndTime' } },
    },
  ],
}

export default Posts

Главный конфиг

// src/payload.config.ts
import { buildConfig } from 'payload/config'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import Posts from './collections/Posts'
import Users from './collections/Users'
import Media from './collections/Media'

export default buildConfig({
  serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL,
  admin: {
    user: Users.slug,
    bundler: webpackBundler(),
  },
  editor: lexicalEditor({}),
  collections: [Posts, Users, Media],
  db: mongooseAdapter({ url: process.env.DATABASE_URI! }),
  // либо PostgreSQL:
  // db: postgresAdapter({ pool: { connectionString: process.env.DATABASE_URI } }),
  upload: {
    limits: { fileSize: 10_000_000 },
  },
  localization: {
    locales: ['ru', 'en'],
    defaultLocale: 'ru',
    fallback: true,
  },
})

Payload поддерживает MongoDB и PostgreSQL через официальные адаптеры. Для PostgreSQL миграции генерируются автоматически:

npx payload migrate:create
npx payload migrate

Интеграция с Next.js 14

Начиная с Payload 2.x поддерживается монтирование в Next.js App Router:

// app/(payload)/admin/[[...segments]]/page.tsx
import { RootPage } from '@payloadcms/next/views'
import config from '@payload-config'

export default RootPage.bind(null, { config })
// app/(payload)/api/[...slug]/route.ts
import { REST_DELETE, REST_GET, REST_PATCH, REST_POST } from '@payloadcms/next/routes'
import config from '@payload-config'

export const GET = REST_GET.bind(null, config)
export const POST = REST_POST.bind(null, config)
export const PATCH = REST_PATCH.bind(null, config)
export const DELETE = REST_DELETE.bind(null, config)

Это означает — один next start, один процесс, один деплой.

Запросы через Local API

Payload предоставляет Local API для серверного кода — без HTTP-оверхеда:

import payload from 'payload'
import config from '@payload-config'

await payload.init({ config })

const posts = await payload.find({
  collection: 'posts',
  where: {
    status: { equals: 'published' },
    publishedAt: { less_than_equal: new Date().toISOString() },
  },
  sort: '-publishedAt',
  limit: 10,
  depth: 2, // populate linked documents
})

REST API работает параллельно и доступен внешним клиентам:

GET /api/posts?where[status][equals]=published&sort=-publishedAt&limit=10

Хуки и расширения

Payload поддерживает хуки на уровне коллекций — до/после операций:

{
  slug: 'posts',
  hooks: {
    beforeChange: [
      async ({ data, operation }) => {
        if (operation === 'create') {
          data.slug = slugify(data.title)
        }
        return data
      },
    ],
    afterChange: [
      async ({ doc }) => {
        await revalidatePath(`/blog/${doc.slug}`)
      },
    ],
  },
}

Кастомные эндпоинты добавляются прямо в коллекцию:

endpoints: [
  {
    path: '/:id/publish',
    method: 'post',
    handler: async (req, res) => {
      await payload.update({
        collection: 'posts',
        id: req.params.id,
        data: { status: 'published', publishedAt: new Date() },
      })
      res.json({ message: 'Published' })
    },
  },
],

Медиа и загрузка файлов

const Media: CollectionConfig = {
  slug: 'media',
  upload: {
    staticURL: '/media',
    staticDir: 'media',
    imageSizes: [
      { name: 'thumbnail', width: 400, height: 300, crop: 'centre' },
      { name: 'card', width: 768, height: 1024 },
      { name: 'hero', width: 1920, height: undefined },
    ],
    adminThumbnail: 'thumbnail',
    mimeTypes: ['image/*', 'application/pdf'],
  },
  fields: [{ name: 'alt', type: 'text' }],
}

Для S3 — официальный плагин @payloadcms/plugin-cloud-storage с адаптером под S3, GCS или Azure.

Сроки

Базовая установка с 3–4 коллекциями, локализацией и интеграцией в Next.js: 5–7 дней. Если нужна кастомная аутентификация, RBAC, сложные хуки — от 2 недель.