React разработка для 1С-Битрикс
CIBlockElement::GetList отдаёт JSON, React его рисует — звучит просто, пока не начнёшь
Главная развилка при старте: как именно React будет забирать данные из Битрикса. От этого зависит вообще всё — сколько кода писать, как деплоить, что с SEO и как потом это поддерживать. За десять лет мы перепробовали все варианты, и у каждого свои грабли.
Архитектурные подходы
SPA на React + REST API Битрикс (BX.rest)
Самый свободный вариант. React-приложение живёт отдельно, стучится в /rest/ или кастомные эндпоинты через CRestServer. Максимум контроля, но и максимум работы.
- Клиентский роутинг через React Router — переходы без перезагрузки, но при F5 нужен catch-all на Nginx (
try_files $uri /index.html) - Оптимистичные обновления: корзина обновляется мгновенно,
sale.basket.updateлетит фоном. Если упал — откатываем стейт и показываем тост - Кэширование через React Query с
staleTime— каталог не дёргает сервер на каждый переход назад - Фронтенд деплоится на CDN независимо от Битрикса — обновил кнопку, не трогая бэкенд
SSR с гидратацией — когда Яндекс не видит SPA
Яндекс научился рендерить JS, но криво. Googlebot лучше, но всё равно не 100%. Серверный рендеринг React-компонентов через Node.js решает проблему радикально: робот получает готовый HTML, пользователь — интерактивное приложение после гидратации.
- FCP уходит ниже секунды на нормальном хостинге
-
og:title,og:imageработают для шаринга в соцсети — без SSR WhatsApp покажет пустую превьюшку - Сложность: нужен Node.js-процесс рядом с Apache/Nginx, который обслуживает Битрикс. Два рантайма, два деплоя, два набора логов
- Кэш Битрикса (
CPHPCache, Композит) можно использовать для прогрева данных, которые потом уходят в SSR
Headless Битрикс — админка для контент-менеджеров, React для посетителей
Контент-менеджер заходит в /bitrix/admin/, редактирует инфоблоки. Посетитель видит React-приложение, которое ходит за данными через API. Классический headless.
- Один бэкенд обслуживает сайт, мобильное приложение и Telegram-бота — через одни и те же эндпоинты
- Масштабирование: React-бандл на CloudFront/CDN, Битрикс на одном сервере. Даже при 50k уников фронтенд не нагружает бэкенд напрямую
- Ловушка: стандартный визуальный редактор Битрикса (
BXEditor) перестаёт работать для посетителей. Контент-менеджерам придётся работать только через админку, без inline-редактирования
Inertia.js — мост без REST API
Inertia прокидывает данные из PHP-контроллера прямо в React-компонент как пропсы. Не нужно писать отдельный API, не нужен сериализатор ответов, не нужен Swagger. Серверная маршрутизация, но клиентский рендеринг.
- Формы:
useForm()из Inertia вместо fetch + обработка ошибок вручную. Серверная валидация приходит автоматически - Авторизация через стандартные сессии Битрикс —
$USER->IsAuthorized()работает как обычно - Минус: жёсткая связка. Фронтенд без бэкенда не работает, отдельное мобильное приложение не подключишь
Стек, который реально используем
| Технология | Зачем именно |
|---|---|
| React 18+ | Suspense, useTransition — UI не блокируется при тяжёлых обновлениях каталога |
| TypeScript | Типизация ответов API Битрикса — IBlockElement, BasketItem, Order. Без этого рефакторинг превращается в русскую рулетку |
| Vite | HMR за 50мс против 3-5 секунд на webpack. На проекте с 200 компонентами разница ощутима |
| React Query | useQuery(['catalog', sectionId]) — автоматический кэш, ревалидация, retry при 503 от перегруженного Битрикса |
| React Hook Form + Zod | Оформление заказа: 15-20 полей, условная валидация (юрлицо — одни поля, физлицо — другие). RHF не ререндерит форму при каждом нажатии клавиши |
| Tailwind CSS | Утилитарные классы. Не боремся с каскадом из template_styles.css Битрикса |
| Radix UI / Shadcn | Доступные примитивы. Модалки, дропдауны, табы — с ARIA из коробки |
Компонентный подход: где грабли
Библиотека компонентов проекта
Каждый проект начинается с дизайн-системы. Не из любви к порядку, а потому что без неё к третьему месяцу три разработчика напишут три разных компонента кнопки.
- Типографика, цвета, отступы — через CSS-переменные и Tailwind-конфиг
- Формы: инпуты с масками (телефон, ИНН), селекты с поиском, загрузка файлов с превью и валидацией MIME
- Карточка товара — отдельная история. Цена с учётом скидок из
CCatalogProduct::GetOptimalPrice(), лейблы «Хит»/«Новинка» из свойств инфоблока, кнопка «В корзину» с состояниями loading/success/error - Таблицы с виртуализацией (react-window) для прайсов на 5000+ строк
Типизация: не формальность, а спасение
Типизируем всё, что приходит из Битрикса. Потому что REST API возвращает string там, где ожидаешь number, "Y"/"N" вместо boolean, и null вместо пустого массива.
// Реальный тип ответа CIBlockElement через REST — сюрпризы повсюду
interface BitrixProduct {
ID: string; // да, string, не number
ACTIVE: "Y" | "N"; // не boolean
PRICE: string; // тоже string
QUANTITY: string; // и это string
}
Zod-схема на входе парсит и трансформирует — компоненты получают нормальные типы.
Производительность: где Битрикс + React тормозит
Главная боль — количество запросов
Стандартная страница каталога: список товаров, фильтры, хлебные крошки, баннер, SEO-текст. Если для каждого блока делать отдельный запрос в REST API — получаем 6-8 запросов по 200-500мс. Итого 2-3 секунды.
Решение — агрегирующие эндпоинты. Один ajax.php или кастомный контроллер на \Bitrix\Main\Engine\Controller собирает все данные для страницы за один запрос. React Query кэширует ответ, повторный заход — из кэша.
Виртуализация — не опция, а необходимость
Каталог с фасетным фильтром может вернуть 500 товаров на страницу (бывает и такое, когда SEO-специалист «оптимизирует» пагинацию). React-window или react-virtuoso рендерят только видимые 20-30 карточек. DOM не разбухает, скролл плавный.
Core Web Vitals — конкретные цифры
-
LCP < 2.5с — lazy loading изображений через
loading="lazy", критический CSS инлайном, прелоад LCP-картинки через<link rel="preload"> -
INP (заменил FID) < 200мс —
useTransitionдля тяжёлых фильтраций,useDeferredValueдля поисковой строки - CLS < 0.1 — фиксированные размеры для скелетонов и изображений. Skeleton-плейсхолдеры вместо спиннеров
Интеграция с API Битрикс: реальность
Стандартный REST — хватает на 30% задач
Из коробки через /rest/ доступны: инфоблоки (iblock.element.get), корзина (sale.basket.*), заказы (sale.order.*), пользователи (user.*). Для простого каталога — достаточно.
Остальные 70% — кастомные контроллеры
\Bitrix\Main\Engine\Controller — стандартный способ создавать свои эндпоинты в D7. Пишем контроллер, регистрируем через registerAction, получаем эндпоинт с CSRF-защитой и авторизацией из коробки.
- Агрегация: один запрос = данные каталога + фильтры + корзина + юзер
- WebSocket через Битрикс Push & Pull (
CPullStack::AddByTag) — статус заказа обновляется в реальном времени, без поллинга - GraphQL-прослойка (webonyx/graphql-php) поверх D7 ORM — фронтенд запрашивает ровно те поля, которые нужны. Экономия трафика на мобильных
Типичные проекты
- Интернет-магазин на 30 000 SKU с фасетным фильтром через
\Bitrix\Iblock\PropertyIndex\Facet— SPA, React Query, виртуализация каталога - B2B-кабинет: персональные цены из
CCatalogGroup, акты сверки из 1С через\Bitrix\Sale\Compatible\OrderCompatibility, история заказов с фильтрацией - Корпоративный портал: дашборды на Recharts, real-time через Push & Pull, интеграция с внутренними API через middleware
- Маркетплейс: два React-приложения (покупатель + продавец), общий бэкенд, разделение данных через
CUser::GetUserGroup()
Сроки
| Тип проекта | Срок |
|---|---|
| Лендинг на React + Битрикс | 2-4 недели |
| Интернет-магазин SPA | 8-16 недель |
| Корпоративный портал | 10-20 недель |
| Миграция фронтенда на React (поэтапно) | 6-12 недель |
Точные цифры — после разбора ТЗ. Оценка поэтапная, с фиксированным бюджетом на каждый спринт.
Почему React, а не Vue или шаблоны Битрикса
- Экосистема. Для любой UI-задачи есть готовая библиотека: таблицы, графики, drag-and-drop, виртуализация
- Кадры. React-разработчика найти в 3 раза проще, чем Битрикс-шаблонщика, знающего D7 и
template.php - React Native. Компоненты переиспользуются в мобильном приложении — не один-в-один, но бизнес-логика и типы шарятся
- Поэтапное внедрение. Можно начать с одного раздела (
/catalog/) на React, остальное оставить на шаблонах Битрикса.component_epilog.phpподключает React-бандл, данные прокидываются черезwindow.__INITIAL_DATA__
1С-Битрикс + React — это не теоретическая архитектура, а рабочая связка, которая уже обслуживает каталоги с десятками тысяч SKU и B2B-кабинеты с тяжёлой бизнес-логикой.







