Налаштування Kirby як Headless CMS через API

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Налаштування Kirby як Headless CMS через API
Середня
~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

Kirby CMS як Headless CMS через API

Kirby CMS має вбудований механізм Content Representations та офіційний headless-режим через KirbyQL або REST. Для production headless рекомендуються офіційний плагін kirby-headless-starter або кастомні маршрути.

Вбудований Content Representations

Kirby дозволяє отримувати контент у JSON через .json.php файли в шаблонах:

// site/templates/blog.json.php
$kirby->response()->json();

echo json_encode([
    'title' => $page->title()->value(),
    'pages' => $page->children()
        ->listed()
        ->filterBy('status', 'published')
        ->sortBy('date', 'desc')
        ->map(fn($post) => [
            'id'      => $post->id(),
            'title'   => $post->title()->value(),
            'slug'    => $post->slug(),
            'url'     => $post->url(),
            'date'    => $post->date()->toDate('Y-m-d'),
            'excerpt' => $post->excerpt()->value(),
            'cover'   => $post->cover()->toFile()?->url(),
        ])
        ->values(),
]);

Запит: GET /blog.json

KirbyQL — GraphQL-подібний API

composer require getkirby/kql
// Запит до /api/query
const response = await fetch(`${KIRBY_URL}/api/query`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Basic ${btoa(`${KIRBY_EMAIL}:${KIRBY_PASSWORD}`)}`,
  },
  body: JSON.stringify({
    query: {
      pages: {
        query: 'page("blog").children.listed.sortBy("date", "desc").paginate(12)',
        select: {
          id: true,
          title: true,
          slug: true,
          url: true,
          date: 'page.date.toDate("Y-m-d")',
          excerpt: true,
          cover: {
            query: 'page.cover.toFile',
            select: { url: true, width: true, height: true, alt: true },
          },
          categories: {
            query: 'page.categories.toPages',
            select: { title: true, slug: true, url: true },
          },
        },
        pagination: { page: 1, limit: 12 },
      },
    },
  }),
});

Аутентифікація API

// site/config/config.php
return [
  'api' => [
    'allowInsecure' => false,
    'basicAuth' => true,
    'cors' => true,
  ],
  'api.cors' => [
    'allowMethods' => 'GET, POST, OPTIONS',
    'allowOrigin'  => env('FRONTEND_URL', '*'),
    'allowHeaders' => 'Authorization, Content-Type',
    'maxAge'       => '300',
  ],
];

Краще використовувати read-only API User:

// site/accounts/[email protected]
<?php return [
  'email'    => '[email protected]',
  'role'     => 'api',
  'password' => password_hash('readonly-password', PASSWORD_DEFAULT),
];

Кастомні API-маршрути

// site/config/config.php
'routes' => [
  [
    'pattern' => 'api/v1/blog',
    'action'  => function () {
      return Response::json([
        'posts' => page('blog')
          ->children()
          ->listed()
          ->sortBy('date', 'desc')
          ->toArray(fn($p) => [
            'title'   => $p->title()->value(),
            'slug'    => $p->slug(),
            'url'     => $p->url(),
            'date'    => $p->date()->toDate('Y-m-d'),
            'excerpt' => $p->excerpt()->value(),
          ]),
      ]);
    },
    'method' => 'GET',
  ],

  [
    'pattern' => 'api/v1/blog/(:any)',
    'action'  => function (string $slug) {
      $post = page('blog/' . $slug);
      if (!$post) return Response::json(['error' => 'Not found'], 404);

      return Response::json([
        'title'   => $post->title()->value(),
        'content' => $post->text()->kirbytext()->value(), // HTML
        'date'    => $post->date()->toDate('Y-m-d'),
      ]);
    },
    'method' => 'GET',
  ],
],

Інтеграція Next.js

// lib/kirby.ts
const KQL_ENDPOINT = `${process.env.KIRBY_URL}/api/query`;
const AUTH = Buffer.from(`${process.env.KIRBY_API_USER}:${process.env.KIRBY_API_PASSWORD}`).toString('base64');

export async function kqlQuery(query: object) {
  const res = await fetch(KQL_ENDPOINT, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Basic ${AUTH}`,
    },
    body: JSON.stringify({ query }),
    next: { revalidate: 3600 },
  });
  return res.json();
}

Налаштування Kirby headless з KQL та Next.js фронтендом — 2–4 дні.