Skip to content
PageBuilder
PageBuilder
Визуальный конструктор секций для MODX 3: черновик и публикация без перезаписи content ресурса
  • MODX 3
  • PHP 8.2
  • Vue 3
  1. Компоненты
  2. PageBuilder
  3. Вывод на сайте
  4. Public API

Public API (Headless) ​

Read-only JSON для внешнего фронта (Next.js, Nuxt, React). Только опубликованный контент PageBuilder. Черновики и запись: Agent API (Pro) или вкладка Секции на форме ресурса в менеджере.

Точка входа:

text
/assets/components/pagebuilder/api.php

Контекст MODX: web. Методы: GET и OPTIONS (CORS preflight).

Включение ​

Три ключа в namespace pagebuilder:

КлючПо умолчаниюОписание
pagebuilder_public_api_enabled0Включить API
pagebuilder_public_api_keyпустоAPI-ключ. Пусто: без ключа (только dev)
pagebuilder_public_api_cors_origins*Разрешённые origins для браузера

После смены ключей очистите кэш сайта, если MODX не подхватил настройки сразу.

Подробнее: Системные настройки → Public API.

Пример переменных на фронте:

bash
PAGEBUILDER_API_URL=https://cms.example.com/assets/components/pagebuilder/api.php
PAGEBUILDER_API_KEY=your-secret-key

Авторизация ​

Если задан pagebuilder_public_api_key, передайте ключ так:

  • заголовок X-PageBuilder-Api-Key: <key> (предпочтительно: ключ не попадает в access-логи)
  • query api_key=<key>

MODX дополнительно проверяет:

  • ресурс опубликован и не удалён
  • policy view на ресурс для гостя web
  • у PageBuilder есть опубликованный snapshot (publishedRevision > 0)

Если API выключен, защищённые endpoints отвечают 404. web/health/ping всё равно работает и возвращает publicApiEnabled.

Формат ответа ​

Тот же envelope, что у connector менеджера:

json
{
  "success": true,
  "message": "",
  "object": {}
}
HTTPПример messageКогда
401Invalid API key.Неверный или отсутствующий ключ
403Access denied.Нет policy view
404Public API is disabled.pagebuilder_public_api_enabled выключен
404Resource not found.Ресурс не найден
404Resource is not published.Ресурс есть, но не опубликован в MODX
404Page has no published content.Ресурс есть, PageBuilder ни разу не публиковали
400resource_id or alias is required.Нет идентификатора
400Invalid action.Неизвестный action=

Endpoints ​

web/health/ping ​

Работает при выключенном API. В ответе поле publicApiEnabled.

bash
curl -s "https://example.com/assets/components/pagebuilder/api.php?action=web/health/ping"
json
{ "success": true, "object": { "ok": true, "publicApiEnabled": true } }

web/page/get ​

Опубликованная страница одного ресурса.

ПараметрОбязателенОписание
resource_id*ID ресурса MODX
alias*Alias ресурса, если нет resource_id
context_keyнетКонтекст для alias, по умолчанию web
includeнетСписок через запятую: document, values, html, sections. По умолчанию document,values
section_typesнетФильтр типов: hero,cta
api_keyесли задан ключAPI-ключ в query

Нужен resource_id или alias.

include ​

ЗначениеВ object
documentПолный опубликованный JSON: sections, trash, schemaVersion, typeVersion, settings, сырой data
valuesВидимые секции и plainText (как [[!PageBuilder? &return_values=1]])
htmlОдна HTML-строка, как сниппет на сайте
sectionsКаждая видимая секция со своим html из Fenom-чанков

values пропускает секции, скрытые UTM, контекстом или Pro conditions. document отдаёт сохранённый JSON как в published_json.

Пример запроса ​

bash
BASE="https://example.com/assets/components/pagebuilder/api.php"

curl -s -H "X-PageBuilder-Api-Key: ${KEY}" \
  "${BASE}?action=web/page/get&alias=about&include=document,values"

Фрагмент ответа object ​

json
{
  "resourceId": 42,
  "publishedRevision": 3,
  "resource": {
    "id": 42,
    "pagetitle": "About",
    "alias": "about",
    "uri": "about.html",
    "context": "web",
    "template": 5
  },
  "document": {
    "schemaVersion": 1,
    "sections": [
      {
        "id": "a1b2c3d4",
        "type": "hero",
        "typeVersion": 1,
        "enabled": true,
        "data": { "title": "Hello" },
        "settings": {}
      }
    ],
    "trash": []
  },
  "values": {
    "plainText": "Hello",
    "sections": [{ "id": "a1b2c3d4", "type": "hero", "enabled": true, "data": { "title": "Hello" } }]
  }
}

При include=sections:

json
{
  "id": "a1b2c3d4",
  "type": "hero",
  "enabled": true,
  "data": { "title": "Hello" },
  "settings": {},
  "html": "<section class=\"pb-section pb-hero\">…</section>",
  "renderFailed": false
}

renderFailed: true значит, что отрисовка чанка не удалась (неизвестный тип, ошибка Fenom). Пропустите блок или покажите запасной вариант в приложении.

JavaScript (fetch) ​

javascript
async function getPage(alias) {
  const url = new URL(process.env.PAGEBUILDER_API_URL)
  url.searchParams.set('action', 'web/page/get')
  url.searchParams.set('alias', alias)
  url.searchParams.set('include', 'document,values')

  const res = await fetch(url, {
    headers: { 'X-PageBuilder-Api-Key': process.env.PAGEBUILDER_API_KEY },
    next: { revalidate: 60 },
  })
  const body = await res.json()
  if (!body.success) throw new Error(body.message)
  return body.object
}

PHP (тот же сайт MODX) ​

php
/** @var \MODX\Revolution\modX $modx */
$api = $modx->services->get(\PageBuilder\PublicApi\PageBuilderPublicApiService::class);
$api->assertEnabled();
$api->assertApiKey($_SERVER['HTTP_X_PAGEBUILDER_API_KEY'] ?? null);

$page = $api->getPage(
    $api->resolveResourceId(0, 'about', 'web'),
    ['include' => 'document,values'],
);

Класс PageBuilder\PublicApi\PageBuilderPublicApiService регистрируется в ServiceRegistry.

web/catalog/list ​

Метаданные типов секций для маппинга section.type на ваши компоненты.

ПараметрОписание
context_keyКонтекст каталога, по умолчанию web
bash
curl -s "${BASE}?action=web/catalog/list&context_key=web&api_key=${KEY}"
json
{
  "success": true,
  "object": {
    "items": [
      {
        "key": "hero",
        "version": 1,
        "label": "Hero",
        "category": "hero",
        "categories": ["hero"],
        "fields": [
          { "name": "title", "type": "text", "label": "Title", "required": true }
        ],
        "thumbnail": ""
      }
    ]
  }
}

Кэшируйте список на час или до деплоя. Он меняется, когда добавляете JSON-типы или UI-типы в панели управления. В ответе типа поле categories: список slug. Поле category остаётся для совместимости.

Таблицы и QueryPolicy ​

Отдельного endpoint таблиц нет. Строки таблиц отдаёт сниппет PageBuilderTableRows или datasource в секции.

QueryPolicy ограничивает datasource-запросы секций в менеджере. Ключи sql, php, snippet, class отклоняются. К query-параметрам api.php он не применяется. Размер страницы списка каталога не больше 100.

CORS ​

В pagebuilder_public_api_cors_origins укажите один origin или список через запятую:

text
https://app.example.com,https://staging.example.com

Preflight:

bash
curl -s -D - -o /dev/null -X OPTIONS \
  "${BASE}?action=web/page/get" \
  -H "Origin: https://app.example.com" \
  -H "Access-Control-Request-Method: GET"

Ожидайте Access-Control-Allow-Origin и Access-Control-Allow-Headers: Content-Type, X-PageBuilder-Api-Key.

Выбор include ​

Задачаinclude
SPA со своими компонентамиdocument или values
Оставить MODX-чанки без переписывания вёрсткиhtml или sections
SEO meta плюс блокиvalues (plainText, поля ресурса)
Один блок на лендингеsection_types=hero&include=document

Headless flow ​

  1. Включите API и задайте ключ в production.
  2. Один раз вызовите web/catalog/list и сохраните схемы полей в кэше (или сгенерируйте TS-типы из fields).
  3. На каждом маршруте вызовите web/page/get по alias или resource_id.
  4. Выводите object.document.sections своими компонентами или используйте object.sections[].html / object.html для SSR-гибрида.
  5. После публикации в менеджере обновляйте кэш, когда меняется publishedRevision.

События ​

СобытиеКогда
pbOnGetValuesinclude содержит values
pbOnBeforeGetListweb/catalog/list

Плагины могут править plainText или скрывать типы так же, как на публичном сайте.

Public API vs Agent API ​

Public APIAgent API (Pro)
URLapi.phpconnector.php
Контекстwebmgr
АвторизацияAPI-ключ (опционально)Сессия менеджера + modAuth
Данныетолько publishedчерновик, схемы, published snapshot
Записьнетmgr/api/page/apply

Free vs Pro ​

ВозможностьFreePro
Public API read (published)дада
Agent API writeнетда
Pro-only типы секций в outputда, если опубликованы на страницеда

Связанные страницы ​