Разработка кастомных полей (Custom Fields) Payload CMS

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка кастомных полей (Custom Fields) Payload CMS
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • 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

Кастомные поля Payload CMS

Payload предоставляет 20+ встроенных типов полей. Для нестандартных случаев — кастомные компоненты React для admin panel при полном сохранении логики валидации и хранения на стороне сервера.

Встроенные поля с продвинутой конфигурацией

Поле с условной видимостью:

{
  name: 'discountPrice',
  type: 'number',
  admin: {
    condition: (data, siblingData) => siblingData.hasDiscount === true,
    description: 'Цена со скидкой',
  },
}

Поле с валидацией:

{
  name: 'phone',
  type: 'text',
  validate: (value) => {
    if (!value) return true
    const phoneRegex = /^\+7\d{10}$/
    if (!phoneRegex.test(value)) {
      return 'Формат: +7XXXXXXXXXX'
    }
    return true
  },
}

Richtext с кастомными функциями:

import { lexicalEditor, LinkFeature, UploadFeature } from '@payloadcms/richtext-lexical'

{
  name: 'content',
  type: 'richText',
  editor: lexicalEditor({
    features: ({ defaultFeatures }) => [
      ...defaultFeatures,
      LinkFeature({ enabledCollections: ['pages', 'posts'] }),
      UploadFeature({ collections: { media: { fields: [{ name: 'caption', type: 'text' }] } } }),
    ],
  }),
}

Кастомный компонент поля

Для отображения нестандартного UI в admin panel, при этом данные хранятся как обычно:

// fields/ColorPicker/index.tsx (admin компонент)
'use client'
import { useField } from 'payload/components/forms'

const ColorPickerField = ({ path }: { path: string }) => {
  const { value, setValue } = useField<string>({ path })

  const colors = ['#FF5733', '#33FF57', '#3357FF', '#FF33A8', '#33A8FF']

  return (
    <div className="field-type">
      <label className="field-label">Цвет</label>
      <div style={{ display: 'flex', gap: 8 }}>
        {colors.map(color => (
          <div
            key={color}
            onClick={() => setValue(color)}
            style={{
              width: 32,
              height: 32,
              borderRadius: '50%',
              background: color,
              cursor: 'pointer',
              border: value === color ? '3px solid #000' : '2px solid transparent',
            }}
          />
        ))}
      </div>
      <input
        type="text"
        value={value || ''}
        onChange={e => setValue(e.target.value)}
        placeholder="#000000"
        style={{ marginTop: 8 }}
      />
    </div>
  )
}

export default ColorPickerField
// collections/Products.ts — подключение кастомного компонента
{
  name: 'brandColor',
  type: 'text',
  admin: {
    components: {
      Field: '/fields/ColorPicker/index#ColorPickerField',
    },
  },
}

Поле Blocks (гибкий конструктор страниц)

// blocks/TextBlock.ts
import { Block } from 'payload/types'

const TextBlock: Block = {
  slug: 'textBlock',
  labels: { singular: 'Текстовый блок', plural: 'Текстовые блоки' },
  fields: [
    { name: 'content', type: 'richText' },
    {
      name: 'columns',
      type: 'select',
      options: [
        { label: '1 колонка', value: '1' },
        { label: '2 колонки', value: '2' },
      ],
      defaultValue: '1',
    },
  ],
}

const ImageBlock: Block = {
  slug: 'imageBlock',
  fields: [
    { name: 'image', type: 'upload', relationTo: 'media', required: true },
    { name: 'caption', type: 'text' },
    { name: 'fullWidth', type: 'checkbox', defaultValue: false },
  ],
}

// В коллекции Pages:
{
  name: 'sections',
  type: 'blocks',
  blocks: [TextBlock, ImageBlock, CTABlock, GalleryBlock],
  minRows: 1,
}

Рендеринг Blocks во фронтенде

// components/Blocks.tsx
import type { Page } from '@/payload-types'

type BlockComponent = {
  textBlock: React.FC<{ content: any; columns: string }>
  imageBlock: React.FC<{ image: any; caption?: string; fullWidth: boolean }>
}

const blockComponents: BlockComponent = {
  textBlock: ({ content, columns }) => (
    <div className={`columns-${columns}`}>
      <RichText content={content} />
    </div>
  ),
  imageBlock: ({ image, caption, fullWidth }) => (
    <figure className={fullWidth ? 'full-width' : ''}>
      <img src={image.url} alt={image.alt} />
      {caption && <figcaption>{caption}</figcaption>}
    </figure>
  ),
}

export const Blocks = ({ sections }: { sections: Page['sections'] }) => {
  return (
    <>
      {sections?.map((block, i) => {
        const Component = blockComponents[block.blockType as keyof BlockComponent]
        if (!Component) return null
        return <Component key={i} {...(block as any)} />
      })}
    </>
  )
}

Виртуальные поля (только admin)

{
  name: 'fullName',
  type: 'text',
  admin: {
    readOnly: true,
    description: 'Вычисляется автоматически',
  },
  hooks: {
    afterRead: [
      ({ data }) => `${data?.firstName} ${data?.lastName}`.trim(),
    ],
  },
}

Сроки

Разработка набора кастомных полей (3–5 нестандартных типов с компонентами) — 2–3 дня.