Barcode Scanner для Payload CMS: сканируем штрихкоды прямо в админке
Приёмка товаров, инвентаризация, учёт оборудования — задачи, где данные быстрее вводить сканером, чем руками. Из коробки админка Payload CMS для таких сценариев не приспособлена: поля редактируются как обычный текст, и о штрихкодах в ней думать не о чем.
Для этой задачи появился плагин @lipecode/barcode-scanner-payloadcms, который добавляет сканирование штрихкодов непосредственно в поля административной панели. Первые публичные версии опубликованы 22 октября 2026 года, код открыт под лицензией MIT.
Репозиторий проекта:
https://github.com/LipeMachado/barcode-scanner-payloadcmsКак это работает
Плагин работает с обычными текстовыми полями. Поле остаётся обычным text-полем Payload со своей валидацией, хуками и Access Control — плагин лишь добавляет рядом с ним кнопку сканирования. После успешного считывания значение записывается в это же поле и дальше обрабатывается Payload как обычно.
Источника ввода три: камера телефона или компьютера, USB-сканер и ручной ввод. Камера работает через библиотеку @zxing/browser — декодирование выполняется в браузере на JavaScript. USB-сканеры, которые передают считанный код как ввод с клавиатуры (keyboard wedge), поддерживаются без дополнительной настройки — плагин распознаёт характерное завершение ввода.
Подключение
Устанавливается плагин обычным способом:
pnpm add @lipecode/barcode-scanner-payloadcmsНастраивается в payload.config.ts: перечисляем коллекции и поля, к которым нужна кнопка сканирования. Например, поле артикула в коллекции товаров:
import { buildConfig } from 'payload'
import { barcodeScannerPlugin } from '@lipecode/barcode-scanner-payloadcms'
export default buildConfig({
collections: [
{
slug: 'products',
fields: [
{ name: 'codeBar', type: 'text', required: true, unique: true },
],
},
],
plugins: [
barcodeScannerPlugin({
fields: [
{
collection: 'products',
field: 'codeBar',
allowManualEntry: true,
usbTerminator: 'Enter',
afterScan: { focusField: 'name' },
},
],
}),
],
})После изменения конфигурации нужно перегенерировать import map админки: pnpm payload generate:importmap.
Настройки и обработка результата
Опций немного, но они закрывают основные сценарии поточного ввода:
allowManualEntry: false— поле в админке становится read-only, заполнить его можно только сканером;usbTerminator— чем завершает передачу USB-сканер:Enter,Tabили таймаут;afterScan.focusFieldиafterScan.submit— после считывания перейти к следующему полю или отправить форму целиком;validation— клиентская проверка считанного кода: длина и шаблон; по умолчанию печатные ASCII от 1 до 256 символов.
Сценарий «отсканировал — сразу перешёл к следующему полю» — ключевой для инвентаризации: складской работник обходит полки со сканером, и форма не должна заставлять его тянуться к мыши.
После успешного сканирования плагин также отправляет событие в браузер — на него можно подписаться и запустить собственный обработчик:
window.addEventListener('payload:barcode-scan', (event) => {
const { code, source, collection, field, path } = (event as CustomEvent).detail
console.log({ code, source, collection, field, path })
})Имя события настраивается опцией eventName. Для собственных экранов за пределами админки плагин экспортирует базовые компоненты — ScannerDialog, UsbScannerInput и хук useCameraScanner; в репозитории они используются в PWA самого автора, так что к админке Payload сканер не привязан жёстко.
Ограничения
Ограничения стоит знать заранее:
- Камера доступна только из безопасного контекста: HTTPS или localhost — стандартное требование браузерного API
getUserMedia. На iOS дополнительно нужен современный Safari либо браузер на тех же WebKit API. - USB-сканер для браузера неотличим от человека за клавиатурой. Опция
allowManualEntry: false— ограничение интерфейса, а не защита: серверную валидацию штрихкодов плагин не добавляет. - Серверной проверки уникальности тоже нет — для уникального артикула нужно
unique: trueв поле или собственный хук. - Повторные считывания с камеры и USB игнорируются в течение 1,5 секунд — при поточном вводе одинаковых кодов подряд это надо учитывать.
- Компонент использует
useFieldPathиз@payloadcms/ui, который сам Payload помечает как экспериментальный.
Насколько доверять
Проекту несколько дней: 22 октября опубликованы сразу три версии — 0.0.0-stage, 0.1.0 и 0.1.1, звёзд на GitHub пока нет, статистика загрузок npm для пакета ещё недоступна. Целевая версия — Payload CMS 3.91.x, React 19+.
При этом к проверкам автор подошёл серьёзно: помимо юнит-тестов, плагин гоняется Playwright-сценариями в реальном Payload-приложении — с настоящим декодированием ZXing из видеофайла вместо камеры, вводом с USB, отказом в доступе к камере и отменой сканирования. Для проекта первой версии это хороший знак.
Мы бы всё же рекомендовали перед рабочим использованием проверить плагин на своём сценарии: отсканировать реальные коды вашим сканером, проверить поведение при плохом освещении и повреждённых этикетках. Откат простой — плагин не меняет схему и данные, из конфигурации убирается одной строкой.
В целом это хороший пример того, как административную панель Payload можно постепенно превращать из обычной CMS в интерфейс для внутренних бизнес-процессов: кнопка сканирования и событие после считывания превращают обычную форму редактирования в инструмент складского учёта.