Интеграция 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 и отдаётся через CDN-backed API. Отличается форматом хранения контента — Portable Text вместо HTML — и возможностью строить редактор под конкретный проект.

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

  • Sanity Content Lake — облачная NoSQL БД с версионированием, транзакциями, real-time обновлениями
  • 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 ?? ''}
                />
            ),
        },
    }}
/>

Real-time обновления (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 — страница обновляется без перезагрузки.

Webhooks

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-based кроп
    .format('webp')
    .quality(80)
    .url()

Сроки

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