Sanity в реальной жизни: CMS, которыми маркетинг-команды продолжают пользоваться
Разница между демо CMS и системой, которой пользуются и через год, сводится к четырём решениям: page-builder из переиспользуемых блоков, роли, live-превью и локализация на уровне полей. Что сработало на NIO, Trivandi и The Savvy Way.

Большинство проектов на CMS отлично смотрятся на демо — и оказываются заброшенными к третьему месяцу. Маркетинговая команда снова шлёт разработчику скриншоты текста, который надо поправить, а дорогая headless-инфраструктура превращается в базу данных, к которой никто не прикасается. Я внедрял Sanity CMS в продакшене примерно в десятке боевых проектов — NIO, Geely UAE, Trivandi, The Savvy Way, Siella Beauty — и те из них, что спустя год по-прежнему в ежедневном использовании, объединяют одни и те же четыре решения. Ни одно из них не про возможности Sanity. Все они про то, смоделировали ли вы контент под тех людей, которые им реально управляют.
Вот где проходит настоящая граница между демо-версией CMS и CMS в продакшене: не в стеке, а в моделировании.
Стройте конструктор страниц из секций, а не стену из полей
Первая ошибка, которую я вижу в доставшихся по наследству проектах на Sanity, — модель контента, повторяющая один конкретный макет из Figma. Один документ homePage с сорока именованными полями — heroTitle, heroSubtitle, featureOneIcon, featureTwoIcon, testimonialQuote. На демо это работает безупречно, потому что в точности совпадает с макетом. А потом маркетинг хочет поднять отзывы над блоком возможностей, или добавить второй отзыв, или переиспользовать блок с ценами на лендинге — и не может. Эта модель — скриншот, а не система.
Выживает же конструктор страниц: массив pageBuilder, в который редактор вставляет и переставляет типизированные секции — герой, текстовая колонка, сетка карточек, медиа, цены, призыв к действию. На этом сайте это 21 тип секции за одним switch (block._type). Один и тот же блок-герой рендерится в кейсе, на странице услуги и на лендинге. Редактор перетаскивает секции в нужном порядке, а фронтенд отрисовывает всё, что он собрал. Добавить секцию — это две правки в схеме плюс React-компонент; и маркетинговая команда больше никогда не заводит тикет на перестановку страницы.
Моделируйте контент, а не страницу. Поле, которое имеет смысл лишь в одной раскладке, — это поле, которое вас попросят перенести через три месяца.
Дисциплина, благодаря которой это работает, — переиспользование. Категории, теги, авторы, контактные данные — это документы-ссылки, а не свободный текст, который перенабирают на каждой странице. В этом проекте контакты и соцсети живут в одном синглтоне siteSettings, на который ссылаются футер, форма обратной связи и JSON-LD. Поменяйте номер телефона один раз — он обновится везде. Как только вы позволите редакторам вводить одно и то же значение в двух местах, значения разойдутся, и кто-нибудь напишет вам про неправильный номер на странице вакансий.

Настройте роли и процессы раньше, чем модель начнёт гнить
Модель контента может быть идеальной и всё равно провалиться — потому что у всех права администратора. Когда каждый редактор может править любое поле, схемы расползаются, обязательный контент удаляется, а черновики публикуются до ревью. Продакшен-Sanity требует трёх вещей, которые большинство демо обходят стороной.
- Настоящие роли. Система ролей Sanity позволяет дать маркетингу доступ к редактированию контентных документов, заперев при этом примыкающие к схеме синглтоны — настройки сайта, навигацию, футер. Редакторы не должны иметь возможности сломать структуру, от которой сами зависят.
- Черновик и публикация как реальная граница. Разделение на черновик и опубликованную версию встроено в Sanity — ничто из набранного редактором не попадает в эфир до публикации. Командам, координирующим запуски, Content Releases позволяют подготовить пакет изменений и опубликовать их вместе в заданное время — это важно, когда страница кампании, изменение цен и баннер должны выйти в эфир одновременно.
- Структура раздела, построенная под команду, а не под схему. Из коробки Sanity показывает плоский список всех типов документов. На крупных сайтах я строю кастомную структуру — здесь страницы организованы в дерево папок, полученное разбиением слага по
/, так что редакторы навигируют по URL-пути ровно так, как они мыслят сайт, а не по типу документа.
Проверка простая: сможет ли новый маркетолог в первый же день опубликовать корректную страницу, не спрашивая разработчика, за что отвечает какое поле? Если нет — модель слишком хитрая.
Почему живой предпросмотр — та самая функция, ради которой CMS принимают
Именно это решает, продолжит ли маркетинговая команда пользоваться CMS. Если редактирование — это набрать текст в форме, нажать «сохранить», переключить вкладку и обновить боевой сайт, чтобы увидеть результат, люди бросают. Цикл обратной связи слишком медленный и слишком неопределённый.
Инструмент Presentation и Live Content API в Sanity замыкают этот цикл. Редактор видит реальную отрисованную страницу рядом с формой, кликает по любому фрагменту текста — и открывается соответствующее поле. Изменения приходят вживую, без танца «сохрани и обнови». На стороне Next.js это компонент <SanityLive>, который подписывается на обновления контента и перерисовывается при мутациях. Редактор перестаёт думать о «полях» и начинает редактировать страницу напрямую — а ровно в этом весь смысл.
Есть одна ловушка, о которой стоит знать, если строите это сами. Визуальное редактирование внедряет в каждую строку невидимые служебные символы (stega), чтобы работала привязка «кликни — отредактируй». Текст для показа можно оставлять как есть, но любую строку, которую вы используете в логике — className, href, сравнение с enum, React-ключ, — нужно сначала очистить, иначе она молча сломается. Каждое сравнение и каждая ссылка на этом сайте проходят через хелпер clean() именно по этой причине. Промахнётесь — и проведёте полдня в раздумьях, почему условие никогда не срабатывает.

Используйте локализацию на уровне полей, которая не ломается
Половина моих клиентов работает больше чем на одном языке — Trivandi на нескольких, а большинству проектов в ОАЭ нужен английский плюс арабский или русский. Неправильный способ это сделать — дублировать весь документ под каждый язык. Тогда у вас два документа, которые расходятся, два слага, которые надо держать синхронными, и редактор, который обновил английскую страницу и забыл про остальные.
Модель, которая выдерживает нагрузку, — это локализация на уровне полей: один документ, и каждое переводимое поле — это массив значений с языковыми метками. Фронтенд разрешает запрошенную локаль с жёстко зашитым откатом на английский, так что страница, существующая только на английском, всё равно корректно отрисуется в любой локали — она никогда не отдаст 404 из-за отсутствующего перевода. Наполовину переведённая страница деградирует мягко, а не ломается.
Одна деталь подставляет всех, кто пишет скрипты для этого: в формате internationalized-array локаль живёт в поле language каждого элемента массива, а не в ключе массива. Ключ — это просто уникальный идентификатор. Я видел миграции, которые записывали локаль в ключ и тихо портили все локализованные поля в датасете. Если пишете массовые правки скриптом, целитесь в language, никогда в ключ.
Локализация теперь сочетается и с AI. У меня настроен Sanity AI Assist с гайдом по переводу в фирменном тоне голоса и списком не-переводимого, так что названия продуктов и брендов — Next.js, Sanity, NIO — остаются в латинице, пока проза получает первый прогон перевода, который затем вычитывает человек. Это не заменяет переводчика. Это убирает этап «чистого листа».

Как продакшен-проект на Sanity выглядит год спустя
Проекты, всё ещё живущие в продакшене, имеют общий профиль. Маркетинговая команда публикует кампании сама, без разработчика в контуре, — это была явная цель на NIO, и эта архитектура легла в основу витрины Geely UAE. Новые страницы собираются из существующих секций за полдня. Переводы выкатываются мягко, даже когда они неполные. А схема не сгнила, потому что у редакторов никогда не было прав ломать те части, что её держат.
Ничего из этого не следует из того, что Sanity — хорошая CMS, хотя она хороша. Это следует из моделирования контента под тех людей, которые редактируют его каждый день, а не под макет, который вы выкатываете на этой неделе. Если вы выбираете headless CMS для маркетинговой команды, это единственный вопрос, который имеет значение, — и та же дисциплина работает, строите ли вы на одном Sanity или дополняете его MedusaJS для коммерции.
Если вам нужна CMS, которой ваша команда действительно пользуется, — это как раз тот тип проектов, что я веду в роли fractional CTO. Что касается коммерции, я разобрал Hydrogen против MedusaJS.
Частые вопросы
Подходит ли Sanity для нетехнических маркетинговых команд?
Да, но только если он смоделирован под них. Sanity даёт инструменты — гибкую модель контента, роли и живой редактор Presentation, — но CMS, переданную в виде стены из сорока полей, забросят независимо от платформы. Принятие в работу обеспечивает конструктор страниц из переиспользуемых секций плюс живой предпросмотр «кликни — отредактируй», а не сам по себе выбор CMS.
В чём разница между локализацией на уровне полей и на уровне документов в Sanity?
Локализация на уровне документов дублирует весь документ под каждый язык — а это два расходящихся документа и слаги, которые надо держать синхронными. Локализация на уровне полей оставляет один документ, где каждое переводимое поле хранит значения с языковыми метками. Именно локализация на уровне полей выживает в продакшене, потому что отсутствующий перевод мягко откатывается на английский, а не оставляет осиротевший, устаревший дубль.
Как работает живой предпросмотр в Sanity в продакшене?
Инструмент Presentation в Sanity отрисовывает ваш настоящий сайт рядом с редактором, а Live Content API передаёт изменения без ручного обновления. В приложении на Next.js компонент `<SanityLive>` подписывается на обновления контента и перерисовывается при каждой мутации. Редакторы кликают по элементу на живой странице, чтобы открыть ровно то поле, которое им управляет.
Нужен ли мне конструктор страниц, или можно моделировать каждую страницу напрямую?
Для разовой страницы, которая никогда не изменится, прямое моделирование подойдёт. Для маркетингового сайта, который растёт и реорганизуется, конструктор страниц из типизированных переставляемых секций — это то, что держит команду самодостаточной. Правило: если поле имеет смысл лишь в одной конкретной раскладке, рано или поздно его придётся переносить — и переносить его будете вы.
Какая самая большая ошибка при массовом редактировании локализованного контента Sanity скриптом?
Запись локали в ключ массива вместо выделенного поля `language`. В формате internationalized-array ключ — это просто уникальный идентификатор, а локаль живёт в `language`. Целиться в ключ при миграции — значит тихо испортить каждое локализованное поле, и это самая частая ошибка в скриптах, которую я встречаю.
Остаётся ли Sanity хорошим выбором в 2026 году?
Да. На середину 2026 года Live Content API, инструмент визуального редактирования Presentation и Content Releases — все стабильны и активно поддерживаются, и они чисто сочетаются с Next.js 16. Но различие создаёт не платформа — а модель контента. Хорошо смоделированный проект на Sanity переживёт плохо смоделированный на любой CMS.
Технологии
Есть похожая задача?
Начать проект→

