На этой странице работает настоящий Payload 2 с базой на этом же сервере. Каждая кнопка бьёт в его живой REST API. Стенд закрывает три вещи, на которых обычно спотыкаются проекты на Payload: мультиязычный контент, доступ по ролям и поля, которые должны считаться сами.
Боль
Живой артефакт
В базе три статьи: две опубликованы, одна черновик. Все запросы уходят как аноним, без токена. Справа сырой ответ API без правок.
Черновик существует: он называется «Чернетка: хуки рахують readingTime». Получить его анонимным запросом не выйдет даже прямым фильтром «всё, что не published», потому что ограничение вшито в access на уровне API, а не в код витрины.
Как устроено
// payload.config.js стенда, фрагменты без сокращений по смыслу localization: { locales: ['uk', 'ru'], defaultLocale: 'uk', fallback: true }, access: { read: ({ req }) => { if (req.user) return true; // редактор видит всё return { status: { equals: 'published' } }; // анониму query constraint }, }, hooks: { beforeChange: [({ data }) => { const words = String(data.body || '').trim().split(/\s+/).length; data.readingTime = Math.max(1, Math.round(words / 180)); if (data.status === 'published' && !data.publishedAt) data.publishedAt = new Date().toISOString(); return data; }], } // slug: beforeValidate, транслитерация из title, стабилен при переводах
Полный конфиг стенда: коллекции users с ролями admin и editor плюс articles с локализованными title, excerpt, body и группой seo. Админка на публичном стенде отключена, наружу проксируются только GET-запросы.
Как проверить
# украинская и русская версия одного документа curl "https://guardlabs.online/demo/payload-cms/api/articles?locale=uk" curl "https://guardlabs.online/demo/payload-cms/api/articles?locale=ru" # попытка вытащить черновики напрямую: totalDocs будет 0 curl "https://guardlabs.online/demo/payload-cms/api/articles?where\[status\]\[not_equals\]=published"