Diil Docs
  1. Документація
  2. З чого почати

Швидкий старт: перший запит за п’ять хвилин

Оновлено:

П’ять хвилин, одна сторінка, нуль адмінок. Наприкінці цього посібника заголовок на вашому сайті надходитиме з CRM Diil — а редактори зможуть змінити його, просто клацнувши по ньому. Наливайте каву; є шанс, що допити не встигнете.

Вам знадобиться:

  • доступ до сайту в CRM Diil (для експериментів можна створити новий);
  • термінал із curl або будь-який інструмент, що вміє надіслати HTTP-запит;
  • будь-який фронтенд: звичайний HTML-файл, React, Next.js, Nuxt — на ваш смак.

Налаштуйте вміст і ключ

  1. Створіть трохи вмісту в CRM

    Відкрийте свій сайт у CRM і переконайтеся, що потрібні мови додано (скажімо, англійську). Потім створіть:

    • сторінку з маркером home;
    • у ній — секцію з маркером hero;
    • у ній — текстовий блок із маркером hero_title і впишіть туди заголовок.

    Маркери — це імена, за якими ваш код знаходить вміст: латинські літери, цифри та підкреслення, 2–40 символів, з урахуванням регістру. Обирайте їх, як назви змінних, — вони житимуть у вашому коді довго. Ось повна картина сторінок, секцій і блоків.

  2. Отримайте ключ сайту

    Перейдіть у Налаштування → Ключі Content API і створіть ключ. Він має вигляд pk_ плюс 32 шістнадцяткові символи й прив’язаний саме до цього сайту.

    Новий ключ зазвичай працює одразу; у гіршому разі дайте йому кілька хвилин. Відкликання працює так само — відкликані ключі отримують 401 invalid_key.

  3. Зробіть перший запит

    Запитайте сторінку home англійською:

    curl "https://back.sitecog.com/content/v1/pages/home?lang=en" \
      -H "x-crm-key: pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40"
    200 OKjson
    {
      "id": 26,
      "marker": "home",
      "name": "Home",
      "href": "/",
      "index": 0,
      "params": {},
      "content": {
        "hero": {
          "id": 41,
          "marker": "hero",
          "name": "Hero",
          "index": 0,
          "show": true,
          "content": {
            "hero_title": {
              "id": 95,
              "marker": "hero_title",
              "name": "Hero title",
              "type": "text",
              "multilang": true,
              "updatedAt": "2026-09-20T16:33:23.000Z",
              "content": { "en": "Earbuds that mute the city" }
            }
          }
        }
      }
    }

    Бачите шлях до заголовка? content.hero.content.hero_title.content.en — сторінка → секція → блок → мова. Кожна сторінка має саме таку форму; подробиці — у розділі Сторінки.

Виведіть на сторінку

Той самий запит у чотирьох варіантах. Оберіть свій — усі роблять одне й те саме: отримують сторінку й вставляють заголовок в <h1>.

<h1 id="hero-title"></h1>

<script type="module">
  const res = await fetch('https://back.sitecog.com/content/v1/pages/home?lang=en', {
    headers: { 'x-crm-key': 'pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40' },
  });
  const page = await res.json();
  const hero = page.content.hero.content;

  document.getElementById('hero-title').textContent = hero.hero_title.content.en;
</script>

Де тримати ключ

Покладіть ключ у змінну оточення, а не в код, — не тому, що він секретний, а тому, що тоді зміна сайту чи ротація ключа — це правка одного рядка.

.env.localbash
# .env.local (Next.js) — лише для сервера, у браузер не потрапляє
CRM_KEY=pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40

# Коду в браузері потрібна публічна змінна. І це нормально: ключ лише для читання.
NEXT_PUBLIC_CRM_KEY=pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40
# Vite: VITE_CRM_KEY=…   Nuxt: NUXT_PUBLIC_CRM_KEY=…

У серверному компоненті (як у вкладці Next.js вище) використовуйте серверну змінну: ключ узагалі не покидає ваш сервер. Для коду в браузері публічна змінна цілком годиться.

Додайте хелпер для мов

Текстові блоки приходять як карти мов: { "en": "…", "de": "…" }. API ніколи не підміняє одну мову іншою: якщо перекладу немає, його просто немає (або це порожній рядок, якщо редактор залишив поле порожнім). Обирати запасну мову — вам, і цей крихітний хелпер робить це одним рядком:

// lib/t.js
// Обираємо переклад: запитана мова → запасна мова → перший непорожній → ''
export function t(map, lang, fallback = 'en') {
  if (!map) return '';
  return map[lang] || map[fallback] || Object.values(map).find(Boolean) || '';
}
Використанняjs
// Мова відвідувача й запасна мова — одним запитом
const res = await fetch('https://back.sitecog.com/content/v1/pages/home?lang=de,en', {
  headers: { 'x-crm-key': 'pk_3f9c2a7e1b4d4c0e8a6f5b2d9c1e7a40' },
});
const page = await res.json();
const hero = page.content.hero.content;

t(hero.hero_title.content, 'de');       // "Kopfhörer, die die Stadt stummschalten"
t(hero.hero_title.content, 'de', 'en'); // німецький ще не заповнили? → англійський текст

Кожен код у ?lang= має бути активною мовою сайту, інакше отримаєте 400 unknown_lang зі списком доступних. Не передасте lang — отримаєте всі активні мови одразу. Уся історія — у розділі Мови та запасна мова.

Увімкніть редагування на сайті

А тепер найцікавіше. Ваша сторінка вже показує вміст із CRM; дозвольмо редакторам змінювати його просто на сторінці, не шукаючи потрібне поле у формі.

  1. Додайте віджет

    Один скрипт, один раз на сторінку, просто перед </body>. Він завантажує редактор лише тоді, коли сайт відкрито всередині CRM, тож звичайні відвідувачі не завантажують із нього ані байта.

    <script src="https://widget.sitecog.com/widget.js" defer></script>
  2. Підкажіть редактору, який елемент показує який блок

    Додайте data-crm-text із маркером блоку до елемента, що його виводить. Текст і далі рендерте з API, як раніше, — атрибут лише пов’язує елемент із блоком.

    <body>
      <h1 data-crm-text="hero_title">Earbuds that mute the city</h1>
    
      <!-- один раз на сторінку, просто перед </body> -->
      <script src="https://widget.sitecog.com/widget.js" defer></script>
    </body>

    У зображень, відео, об’єктів і масивів свої атрибути (data-crm-image, data-crm-video, data-crm-object, data-crm-array) — див. Віджет і розмітка. Для відвідувачів атрибути нешкідливі, тож лишайте їх і в продакшені.

  3. Дозвольте CRM вбудовувати ваш сайт у фрейм

    Режим Live відкриває ваш сайт усередині CRM, в iframe. Ваш сервер має дозволити це через frame-ancestors і не надсилати X-Frame-Options: DENY чи SAMEORIGIN. Інакше CRM повідомить, що сайт забороняє вбудовування.

    // next.config.js
    module.exports = {
      async headers() {
        return [{
          source: '/:path*',
          headers: [
            { key: 'Content-Security-Policy', value: "frame-ancestors 'self' https://sitecog.com" },
          ],
        }];
      },
    };
  4. Клацніть, введіть, збережіть

    Відкрийте сайт у CRM у режимі Live, клацніть по заголовку, змініть його й збережіть. CRM записує блок, версія вмісту зростає, ваша сторінка отримує свіжий вміст — і новий заголовок уже на місці. 🎉

    Бонус: якщо додати data-crm-text="promo_note" на елемент ще до того, як такий блок з’явиться, редактор зможе створити блок просто із сайту.

Оминайте кеш для редакторів

Наш бік ніколи не віддає застарілий вміст у режимі Live. А от ваш кеш може: з revalidate: 60 редактор може зберегти зміни й ще до хвилини бачити старий текст. Усередині фрейму CRM до URL додається ?crm_live=1 — використайте його, щоб робити запит із cache: 'no-store':

// app/page.tsx — оминаємо будь-який кеш, поки дивиться редактор
const API = 'https://back.sitecog.com/content';

export default async function Home({ searchParams }: { searchParams: Promise<{ crm_live?: string }> }) {
  const live = (await searchParams).crm_live === '1';

  const res = await fetch(API + '/v1/pages/home?lang=en', {
    headers: { 'x-crm-key': process.env.CRM_KEY! },
    ...(live ? { cache: 'no-store' as const } : { next: { revalidate: 60 } }),
  });
  const page = await res.json();
  const hero = page.content.hero.content;

  return <h1 data-crm-text="hero_title">{hero.hero_title.content.en}</h1>;
}

Що далі

Вміст надходить, редактори клацають. Ось куди копати глибше: