Как мы запустили региональную EV-платформу NIO — архитектурные решения, которые сыграли роль
Разбор кейса региональной EV-платформы NIO: кастомный конфигуратор, синхронизация товаров через MedusaJS, запись в шоурум и самостоятельная Sanity CMS — какие архитектурные решения сработали и что я бы изменил.

Когда глобальный бренд электромобилей попросил нас запустить его региональную платформу в регионе MENA, бриф звучал не как «сделайте сайт». Нужны были конфигуратор, коммерческий бэкенд, флоу записи в шоурум и контентная система, которой региональная команда маркетинга могла бы управлять, ни разу не заводя тикет на разработчика, — и всё это к дате запуска, которую никто не собирался сдвигать. Самое интересное в региональной EV-платформе NIO — не список фич. Это headless-архитектура электронной коммерции под капотом: то, как фронтенд на Next.js, CMS Sanity и коммерческое ядро MedusaJS были связаны так, что четыре отдельные системы выглядели для покупателя как один продукт и при этом оставались дешёвыми в изменении для команды. Это разбор по существу — решения, которые сыграли роль, то, что выдержало реальный региональный трафик, и то, что я сделал бы иначе.

Ограничение, которое определило каждое архитектурное решение
NIO пришли с ограничениями, которых ждёшь от глобального автомобильного бренда: жёсткие бренд-стандарты, очередь из стейкхолдеров и непреклонный дедлайн. Но ограничением, которое на самом деле определило архитектуру, было самое скучное — передача проекта. Что бы мы ни построили, этим должна была уметь управлять региональная команда маркетинга без единого инженера в штате, и она должна была продолжать этим управлять год спустя, когда нас на проекте уже не будет.
Одно это требование убило кучу соблазнительных срезов углов. Контент не мог жить в коде. Цены не могли быть захардкоженным JSON-файлом, о существовании которого кто-то забудет. А коммерческий слой должен был быть тем, чем мы владеем и что можем передать, — не SaaS-аккаунтом с привязанной к нему дорожной картой вендора. Если вы читали, почему я опираюсь на headless-решения для серьёзной коммерции, то здесь весь этот аргумент в одном проекте.
Почему мы построили кастомный конфигуратор, а не взяли готовый
Конфигуратор автомобиля — очевидное место, где так и тянет взять сторонний виджет. Мы не стали, и я бы каждый раз принимал это решение снова.
Готовые автомобильные конфигураторы оптимизированы под каталог дилера, а не под опыт бренда. Они приходят со своим DOM, со своими лазейками для стилизации и со своим представлением о том, как устроено ценообразование, — которое никогда не совпадает с регионом, где пошлины, пакеты опций и валюта отличаются от глобального дефолта. В тот момент, когда конфигуратор должен учитывать специфичные для MENA правила ценообразования и при этом ощущаться как NIO, а не как универсальный плагин, виджет «для экономии времени» превращается в то, с чем ты воюешь три спринта.
Поэтому мы построили его как стейт-машину на React поверх дерева модели, комплектации, цвета и опций, с расчётом цены вживую на стороне коммерческого слоя, а не вшитой во фронтенд. Задача конфигуратора — отрисовать варианты и вычислить корректный выбор; *цена* этого выбора — всегда ответ коммерческого слоя. Именно это разделение позволило менять цены без деплоя — и именно поэтому региональное обновление цен ни разу не затронуло код фронтенда.

MedusaJS как источник истины, а не кнопка оформления заказа
Принято считать, что «headless-коммерция» — это SDK оформления заказа, прикрученный к маркетинговому сайту. На NIO всё было наоборот: MedusaJS был хребтом, а витрина — лишь его представлением для чтения.
Автомобили, аксессуары, комплектации, региональные цены и наличие — всё живёт в Medusa как единый источник истины. Приложение на Next.js читает оттуда, конфигуратор сверяется с этим, а флоу шоурума привязывает лиды к тому же каталогу. Мы выбрали Medusa именно потому, что это open-source и полностью наша собственность — никакой посемейной SaaS-тарификации, никакого каталога, с которого пришлось бы мигрировать при смене контракта, и модульная система, которую можно расширить под те части автомобильной коммерции, что ни одна платформа не даёт из коробки. Полное дерево решений Hydrogen против Medusa я расписал отдельно, но коротко для NIO: сложный каталог с региональными ценами, которым клиенту нужно владеть от и до, указывает на Medusa, а не на Shopify Hydrogen.
Синхронизация между Medusa и витриной — это место, где headless-архитектуры обычно гниют. Ошибка в том, чтобы относиться к фронтенду как к кэшу, который нужно вручную инвалидировать, — в итоге получаешь кладбище ревалидационных вебхуков, которым никто не доверяет. Мы держали путь чтения простым: витрина подтягивает данные каталога и цен типизированными серверными вызовами в момент запроса для всего ценочувствительного и статически генерирует только по-настоящему статическую маркетинговую оболочку. Неверная цена на автомобиль хуже, чем чуть более медленная страница, — а серверные компоненты позволяют делать этот компромисс на уровне маршрута, а не для всего приложения сразу.
CMS, которой команда маркетинга действительно пользуется
Причина, по которой в этом стеке стоит Sanity, а не более тяжёлая традиционная CMS, — снова требование передачи проекта. Команда MENA публикует кампании, обновления страниц моделей и новости ежедневно, на двух языках, без разработчика в цепочке. Это работает только если модель контента выстроена вокруг *того, что редактирует команда*, а не вокруг вёрстки страницы.
Поэтому мы смоделировали структурированные типы контента — кампания, страница модели, новостная запись — с локализацией на уровне полей, а не дублированием документов под каждый язык. Редактор меняет заголовок один раз и правит перевод прямо рядом с ним; фронтенд резолвит запрошенную локаль с откатом на английский. Урок, который я раз за разом переучиваю и описал в Sanity в реальном мире, в том, что разница между демо CMS и CMS, которой всё ещё пользуются ежедневно год спустя, почти целиком в моделировании контента и превью. Мы дали им настоящее визуальное редактирование — кликнул по заголовку в живом превью, поправил его на месте — потому что команда маркетинга, которая видит своё изменение до публикации, действительно публикует.
Тест CMS — это не демо на запуске. Это то, редактирует ли кто-то в ней двенадцать месяцев спустя, не звоня вам.

Запись в шоурум: неприметная система, которая отбила своё
Флоу записи — тест-драйвы и визиты в шоурум — выглядел как самый маленький кусок, а оказался тем, что бизнес ценил больше всего, потому что именно здесь платформа производит лиды. Мы завели записи в воронку лидов со сквозным трекингом, чтобы маркетинг видел весь путь от взаимодействия с конфигуратором до забронированного визита, а не отправку формы, висящую в изоляции.
Технически здесь нет ничего сложного. Архитектурным решением, которое сыграло роль, было держать сервис записи отдельной ограниченной зоной ответственности, которая *ссылается* на каталог, а не переписывает его заново, — так что модель, ушедшая в out of stock в Medusa, отражается в том, на что можно записаться, при нуле дублированных данных.
Что выдержало — и что я сделал бы иначе
Платформа запустилась в срок и с тех пор в продакшене: конфигуратор, записи и синхронизация коммерции обслуживают реальных покупателей по всему региону. Эта же архитектура стала фундаментом для нашего следующего регионального автомобильного проекта — витрины Geely в ОАЭ, — что и есть самый сильный сигнал, что форма была правильной. Хорошая архитектура — та, которую хочется переиспользовать.
Что выдержало:
- Дисциплина единого источника истины. Один каталог в Medusa, всё остальное читает его. На любой вопрос «откуда взялась эта цифра» был ровно один ответ.
- Локализация на уровне полей вместо документов под каждый язык. Команда вообще о ней не думает — а это и есть цель.
- Выбор рендеринга на уровне маршрута. Статическая маркетинговая оболочка, динамические цены. Быстро там, где можно, корректно там, где нужно.
Что я сделал бы иначе:
- Мы строили на Next.js 15. Next.js 16 — текущая стабильная линия по состоянию на середину 2026 года, с App Router по умолчанию и React Compiler, который теперь стабилен (хотя всё ещё включается опционально, а не по умолчанию). На новом проекте сегодня я бы стартовал на 16 и включил компилятор, чтобы он взял на себя мемоизацию, которую мы частично делали руками. Путь обновления — реальная работа, но её стоит запланировать, а не откладывать бесконечно.
- Более ранние вложения в превью-окружения. Мы добавили надёжные превью на каждую ветку после того, как пара циклов ревью со стейкхолдерами стала шумной. На Geely мы настроили это в первый же день, и ревью стало заметно спокойнее.
- Более тонкий слой состояния конфигуратора. Наша первая версия держала на клиенте больше производного состояния, чем было нужно. Более чистая версия вычисляет меньше и больше спрашивает у коммерческого слоя — меньше мест, где фронтенд и каталог могут разойтись.
Если из этой headless-архитектуры коммерции и есть один переносимый урок, то он в том, что сложные решения — не про то, какой фреймворк. Они про то, где живёт истина, кто что может менять без деплоя и смогут ли люди, наследующие систему, действительно ею управлять. Сделайте эти три вещи правильно — и Next.js, Sanity и Medusa станут просто деталями, которые делают её быстрой.
Частые вопросы
Что такое headless-архитектура электронной коммерции?
Headless-архитектура электронной коммерции отделяет витрину (то, что видит покупатель) от коммерческого движка (каталог, цены, заказы) и от системы контента (маркетинговые тексты, кампании). Они общаются по API. На NIO это означало фронтенд на Next.js, который читает коммерцию из MedusaJS, а контент — из Sanity, причём каждым слоем можно владеть и менять его отдельно, так что обновление цен или правка текста ни разу не требовали передеплоя остальных.
Почему для такого проекта использовать MedusaJS, а не Shopify?
MedusaJS — open-source и полностью ваша собственность, что важно, когда клиенту нужно владеть сложным каталогом с региональными ценами от и до, без посемейной SaaS-тарификации. Shopify с Hydrogen быстрее поднять для стандартных розничных каталогов. Честное дерево решений сводится к сложности каталога, владению и бюджету — я разбираю это в [Hydrogen против Medusa](/insights/hydrogen-vs-medusa).
Может ли нетехническая команда маркетинга действительно вести Sanity CMS сама?
Да, но только если модель контента спроектирована вокруг того, что они редактируют, а не вокруг вёрстки страницы, и только если у них есть визуальные превью. Команда на NIO публикует ежедневно на двух языках без участия разработчиков. Провальный сценарий — моделировать контент так, чтобы он зеркалил ваши компоненты: это рождает CMS, которой редакторы избегают. Локализация на уровне полей и превью с правкой по клику — вот что делает это устойчивым.
Подходит ли Next.js для конфигуратора автомобиля?
Да. Конфигуратор — это интерактивное состояние клиента (выборы), наложенное на истину, полученную с сервера (цены, наличие). Next.js с React позволяет держать интерактивное состояние на клиенте, резолвя всё ценочувствительное на сервере на каждый запрос, так что конфигуратор никогда не покажет тихо устаревшую цену. Именно сборка его кастомно, а не использование готового виджета, позволяет ему соответствовать бренду и правилам ценообразования региона.
Каково текущее состояние Next.js для такого проекта в 2026 году?
По состоянию на середину 2026 года текущая стабильная линия — Next.js 16, App Router идёт по умолчанию, а React Compiler стабилен (опционален, пока не включён по умолчанию). Платформа NIO вышла на Next.js 15; на новом проекте сегодня я бы стартовал на 16 и включил компилятор, чтобы мемоизация делалась автоматически. Архитектурные паттерны — серверные компоненты, выбор рендеринга на уровне маршрута — переносятся между двумя версиями без проблем.
Как держать витрину и коммерческие данные в синхронизации без ревалидационного хаоса?
За счёт того, что не относиться к витрине как к кэшу, который инвалидируется вручную. Ценочувствительные данные (цены, наличие) подтягиваются на сервере в момент запроса, поэтому они всегда актуальны; предгенерируется только по-настоящему статическая маркетинговая оболочка. Это избавляет от кладбища ревалидационных вебхуков, которое накапливают headless-проекты, и означает, что каталог в Medusa остаётся тем единственным источником истины, о синхронизации которого никому не нужно помнить.
Технологии
Есть похожая задача?
Начать проект→

