Секція — це одна горизонтальна смуга сторінки (перший екран, таблиця цін, FAQ) разом з усіма її блоками. Зазвичай секції приходять вам безкоштовно всередині /v1/pages/:marker. А цей ендпоінт — для моментів, коли хочеться лише одного шматочка, а не цілого торта.
Коли секція краща за цілу сторінку
Запит цілої сторінки — як і раніше варіант за замовчуванням, і для більшості сторінок він правильний: один запит, усе всередині. Окрема секція виграє в кількох конкретних ситуаціях:
- Лінива підвантажка нижче першого екрана. Сторінка довга, карусель відгуків живе десь на четвертому прокручуванні, і більшість відвідувачів туди не доходить. Візьміть сторінку з
?emptyзаради заголовка й метатегів, запитайте секції першого екрана за маркерами, а важкі тягніть, лише коли відвідувач до них догортає. - Спільні секції. Футер, смуга з підпискою на розсилку, блок контактів «Залишилися питання?», який є на кожній сторінці. Тримайте його в CRM в одному примірнику й запитуйте за маркером скрізь, де він потрібен.
- Оновлення однієї частини. Клієнтському віджету, якого цікавить лише одна секція, — скажімо, промозона, яку ви перевіряєте за таймером, — не треба щоразу завантажувати всю сторінку.
Отримати одну секцію
/v1/sections/:markerhttps://back.sitecog.com/content/v1/sections/:marker
content. Форма точно та сама, що й у секції всередині відповіді зі сторінкою, тож обидва випадки обслуговує той самий код рендерингу.Параметри
markerpathstringобовʼязковоhero чи reviews. Правила ті самі, що й для маркерів сторінок: латинські літери, цифри й підкреслення, 2–40 символів, з урахуванням регістру. Секція знаходиться лише за маркером — параметра сторінки немає, — тож секціям, які ви запитуєте так, давайте маркери, що не повторюються на інших сторінках.langquerystringнеобовʼязковоЗа замовчуванням: усі активні мови?lang=en, ?lang=en,de або ?lang=en&lang=de. Кожен код має бути активною мовою сайту, інакше отримаєте 400 unknown_lang. Див. «Мови та запасна мова».emptyqueryflagнеобовʼязковоЗа замовчуванням: вимкненоcontent — лише id, маркер, назву, index і show. Є параметр — увімкнено: ?empty, ?empty=1, ?empty=true; вимикається значенням 0 або false. Зручно для дешевої перевірки «а ця секція взагалі увімкнена?» перед завантаженням чогось важкого.x-crm-keyheaderstringобовʼязково?key=. Див. «Ключі сайту».Приклад запиту
curl "https://back.sitecog.com/content/v1/sections/reviews?lang=en" \
-H "x-crm-key: pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40"const res = await fetch('https://back.sitecog.com/content/v1/sections/reviews?lang=en', {
headers: { 'x-crm-key': 'pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40' },
});
if (!res.ok) throw new Error(`Content API: ${res.status}`);
const section = await res.json();
if (section.show) {
console.log(section.content.reviews_title.content.en); // "What people say"
}'use client';
import { useEffect, useRef, useState, type ReactNode } from 'react';
// Ключ сайту публічний за задумом, тож у браузері йому саме місце
const KEY = process.env.NEXT_PUBLIC_CRM_KEY!;
export function LazySection({ marker, lang, render }: {
marker: string;
lang: string;
render: (section: any) => ReactNode;
}) {
const ref = useRef<HTMLDivElement>(null);
const [section, setSection] = useState<any>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const io = new IntersectionObserver(async ([entry]) => {
if (!entry.isIntersecting) return;
io.disconnect(); // завантажуємо один раз
const res = await fetch(`https://back.sitecog.com/content/v1/sections/${marker}?lang=${lang}`, {
headers: { 'x-crm-key': KEY },
});
if (res.ok) setSection(await res.json());
}, { rootMargin: '400px' }); // починаємо трохи раніше, ніж секцію стане видно
io.observe(el);
return () => io.disconnect();
}, [marker, lang]);
return <div ref={ref}>{section?.show ? render(section) : null}</div>;
}Приклад відповіді
{
"id": 47,
"marker": "reviews",
"name": "Customer reviews",
"index": 4,
"show": true,
"content": {
"reviews_title": {
"id": 120,
"marker": "reviews_title",
"name": "Title",
"type": "text",
"multilang": true,
"updatedAt": "2026-09-21T11:02:15.000Z",
"content": { "en": "What people say" }
},
"reviews_list": {
"id": 121,
"marker": "reviews_list",
"name": "Reviews",
"type": "array",
"multilang": false,
"updatedAt": "2026-09-25T08:40:03.000Z",
"content": [
{
"author": { "en": "Maria, Berlin" },
"text": { "en": "Finally I can hear my podcast on the U-Bahn." },
"rating": 5
}
]
}
}
}З ?empty той самий запит повертає лише верхню частину — зручно, коли треба знати тільки те, чи увімкнена секція:
{
"id": 47,
"marker": "reviews",
"name": "Customer reviews",
"index": 4,
"show": true
}Поля відповіді
idnumbermarkerstringnamestringindexnumbershowbooleancontent{ [blockMarker]: Block }?empty.content →
idnumbermarkerstringreviews_title.namestringtypestringtext, html, image, video, link, number, color, date, date_range, boolean, object, array. Від нього залежить форма content.multilangbooleanupdatedAtstring (ISO 8601)contentзалежить від типу{ file } для одного зображення, масив елементів для array тощо. Усі форми — на сторінці «Типи блоків».Прапорець show: приховано — не означає видалено
Редактори можуть вимкнути секцію в CRM, не видаляючи її, — для сезонної акції, недописаного FAQ чи блока, що чекає на юристів. API однаково повертає таку секцію з "show": false і всім її вмістом. Вирішити не рендерити її — робота вашого шаблону:
const reviews = await getSection('reviews');
return (
<>
<Hero />
{reviews.show && <Reviews section={reviews} />}
</>
);Помилки
| Статус | Тіло | Що сталося |
|---|---|---|
| 400 | {"message":"invalid_marker"} | У маркері є символи поза A–Z a–z 0–9 _ або в нього неправильна довжина. |
| 400 | {"message":"invalid_lang", …} | Код у lang має неправильний формат (скажімо, english замість en). |
| 400 | {"message":"unknown_lang", …} | Мова з lang не активна на сайті. У тілі відповіді — список доступних. |
| 401 | {"message":"invalid_key"} | Ключа немає, він зіпсований або відкликаний. |
| 404 | {"message":"section_not_found"} | На цьому сайті немає секції з таким маркером. Одруківка? Ключ іншого сайту? |
| 429 | {"message":"rate_limit_exceeded"} | Забагато запитів за цю хвилину. Див. «Ліміти запитів». |
Повний список із рецептами виправлення — на сторінці «Помилки».