Інтеграція CMS Sanity для управління контентом

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

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

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Інтеграція CMS Sanity для управління контентом
Середня
~3-5 робочих днів
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • 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

Інтеграція CMS Sanity для управління контентом

Sanity — це headless CMS з повністю налаштовуваною схемою та редактором (Sanity Studio). Контент зберігається в хмарній інфраструктурі Sanity і поставляється через API з підтримкою CDN. Відрізняється форматом зберігання контенту — Portable Text замість HTML — та можливістю побудови редактора, специфічного для вашого проекту.

Архітектура Sanity

  • Sanity Content Lake — хмарна NoSQL БД з версіюванням, транзакціями, оновленнями в реальному часі
  • Sanity Studio — налаштовуване React-приложення редактора, розгортається на будь-якому хостингу
  • GROQ API — власна мова запитів (Graph-Relational Object Queries)
  • CDN API — кешовані запити через cdn.sanity.io для продакшену

Ініціалізація проекту

npm create sanity@latest -- --project my-project --dataset production --template clean
cd my-project
npm run dev  # Studio на http://localhost:3333

Для підключення до існуючого проекту:

npm install @sanity/client
// lib/sanity.ts
import { createClient } from '@sanity/client';

export const client = createClient({
    projectId: 'abc123xyz',
    dataset: 'production',
    apiVersion: '2024-01-01',
    useCdn: true,  // true для публічного контенту, false для приватного/свіжого
});

Визначення схеми

Схема — TypeScript/JavaScript, описує типи документів та їхні поля:

// schemas/article.ts
import { defineType, defineField } from 'sanity';

export const article = defineType({
    name: 'article',
    title: 'Стаття',
    type: 'document',
    fields: [
        defineField({
            name: 'title',
            title: 'Заголовок',
            type: 'string',
            validation: (Rule) => Rule.required().min(5).max(120),
        }),
        defineField({
            name: 'slug',
            title: 'Slug',
            type: 'slug',
            options: { source: 'title', maxLength: 96 },
        }),
        defineField({
            name: 'cover',
            title: 'Обкладинка',
            type: 'image',
            options: { hotspot: true },
            fields: [
                { name: 'alt', type: 'string', title: 'Alt текст' },
            ],
        }),
        defineField({
            name: 'body',
            title: 'Контент',
            type: 'array',
            of: [
                { type: 'block' },  // Portable Text
                { type: 'image', options: { hotspot: true } },
                { type: 'code' },   // блок коду (з sanity-plugin-code-input)
            ],
        }),
        defineField({
            name: 'publishedAt',
            type: 'datetime',
        }),
        defineField({
            name: 'categories',
            type: 'array',
            of: [{ type: 'reference', to: [{ type: 'category' }] }],
        }),
    ],
    preview: {
        select: { title: 'title', media: 'cover' },
    },
});

GROQ-запити

GROQ — декларативна мова запитів, специфічна для Sanity. Потужніша за REST-фільтрацію:

// Всі опубліковані статті з даними категорій
*[_type == "article" && defined(publishedAt) && publishedAt <= now()] | order(publishedAt desc) [0..9] {
  _id,
  title,
  slug,
  publishedAt,
  "cover": cover.asset->url,
  "categories": categories[]->{ _id, title, slug }
}
// Виконання запиту
const articles = await client.fetch(
    `*[_type == "article"] | order(publishedAt desc) [0..$limit] {
        _id, title, slug, publishedAt
    }`,
    { limit: 10 }
);

// Конкретна стаття за slug
const article = await client.fetch(
    `*[_type == "article" && slug.current == $slug][0] {
        title,
        body,
        "author": author->{ name, image }
    }`,
    { slug: 'my-article-slug' }
);

Portable Text

Замість HTML контент зберігається як структурований JSON:

[
  { "_type": "block", "style": "h2", "children": [{ "_type": "span", "text": "Введення" }] },
  { "_type": "block", "style": "normal", "children": [
    { "_type": "span", "text": "Звичайний текст з " },
    { "_type": "span", "marks": ["strong"], "text": "жирним" },
    { "_type": "span", "text": " словом." }
  ]},
  { "_type": "image", "asset": { "_ref": "image-abc123-800x600-jpg" } }
]

Для рендеринга в React:

import { PortableText } from '@portabletext/react';
import imageUrlBuilder from '@sanity/image-url';

const builder = imageUrlBuilder(client);

<PortableText
    value={article.body}
    components={{
        types: {
            image: ({ value }) => (
                <img
                    src={builder.image(value).width(800).url()}
                    alt={value.alt ?? ''}
                />
            ),
        },
    }}
/>

Оновлення в реальному часі (Live Preview)

// next.js: app/[slug]/page.tsx з live preview
import { useLiveQuery } from '@sanity/preview-kit';

const { data: article } = useLiveQuery(initialArticle, articleQuery, { slug });

Sanity GROQ Streaming API відправляє оновлення через Server-Sent Events при зміні контенту в Studio — сторінка оновляється без перезагрузки.

Вебхуки

Sanity Console → API → Webhooks → Create
URL: https://example.com/api/revalidate
Trigger on: create, update, delete
Filter: _type == "article"
Secret: webhook-secret-key
// Next.js API route для ISR revalidation
export async function POST(req: Request) {
    const signature = req.headers.get('sanity-webhook-signature');
    // перевірити підпис за допомогою @sanity/webhook-toolkit
    await revalidatePath('/blog');
    return Response.json({ revalidated: true });
}

Управління ресурсами зображень

Sanity трансформує зображення на льоту через URL-параметри:

builder.image(source)
    .width(1200)
    .height(630)
    .fit('crop')
    .crop('focalpoint')  // кроп на основі hotspot
    .format('webp')
    .quality(80)
    .url()

Терміни

Налаштування проекту Sanity, схема, Studio, GROQ-запити, інтеграція з Next.js — 3–5 робочих днів. Live preview, користувальницькі плагіни Studio, вебхуки, користувальницькі поля — +3–4 дні.