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-розробника знайти втричі простіше, ніж Бітрікс-шаблонника, який знає D7 і
template.php - React Native. Компоненти перевикористовуються в мобільному застосунку — не один-в-один, але бізнес-логіка і типи шаряться
- Поетапне впровадження. Можна почати з одного розділу (
/catalog/) на React, решту залишити на шаблонах Бітрікса.component_epilog.phpпідключає React-бандл, дані прокидуються черезwindow.__INITIAL_DATA__
1С-Бітрікс + React — це не теоретична архітектура, а робоча зв'язка, яка вже обслуговує каталоги з десятками тисяч SKU та B2B-кабінети з важкою бізнес-логікою.







