Ми часто стикаємося з ситуацією, коли штатний пошук Бітрікс перестає справлятися з навантаженням інтернет-магазину. Стандартний модуль search з морфологічним індексом у таблицях b_search_content і b_search_stem дає 800–1200 мс відповіді та не підтримує instant search. Це критично для каталогів з 50 000+ SKU: покупці йдуть, не дочекавшись результату. Ми розробляємо кастомний пошук на React під каталоги від 10 000 до 500 000 SKU. Наш досвід — понад 10 років у Бітрікс-розробці, десятки впроваджень, включаючи інтеграцію з 1С через CommerceML та торгові каталоги будь-якої складності. Для каталогів з 10 000 SKU витрати на інфраструктуру мінімальні, а приріст конверсії від швидкого пошуку сягає 15–20%.
Вибір пошукового двигуна
Elasticsearch / OpenSearch — виправдані при об'ємі >100 000 документів, необхідності full-text search з морфологією, буст-ранжуванні, синонімах. Вимагають окремого сервера. Typesense — більш проста альтернатива з хорошою продуктивністю, простіше в адмініструванні. Підходить для середнього каталогу. Meilisearch — швидкий старт, fuzzy search з коробки, хороша документація. Для каталогів до 500 000 товарів. Кастомний SQL (Бітрікс) — FULLTEXT INDEX в MySQL або tsvector в PostgreSQL. Працює без додаткової інфраструктури, достатньо для каталогів до 50 000 SKU.
Порівняння двигунів:
| Двигун |
Об'єм |
Продуктивність |
Складність інфраструктури |
| Elasticsearch |
>100 000 |
Висока |
Висока |
| Meilisearch |
до 500 000 |
Висока |
Середня |
| Typesense |
до 300 000 |
Висока |
Низька |
| SQL (MySQL/PostgreSQL) |
до 50 000 |
Середня |
Нульова |
Meilisearch обробляє запити в 10 разів швидше штатного пошуку Бітрікс — це підтверджено нашими тестами для каталогів до 500 000 товарів.
Як вибрати двигун під свій каталог?
Для більшості середніх інтернет-магазинів (до 100 000 SKU) рекомендую Meilisearch або кастомний PostgreSQL full-text. Elasticsearch — тільки якщо вже є інфраструктура або потрібна складна аналітика пошуку.
Індексація товарів Бітрікс
Незалежно від обраного двигуна, потрібна синхронізація даних між Бітрікс і пошуковим індексом. Використовуємо подію OnProductUpdate (подія зміни товару в 1С-Бітрікс) для постановки задачі у фонову чергу.
Приклад коду індексатора
// Обробник події зміни товару
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'catalog', 'OnProductUpdate',
function(\Bitrix\Main\Event $event) {
$productId = $event->getParameter('id');
\Local\Search\IndexQueue::add($productId, 'update');
}
);
// Індексатор (виконується через cron)
class ProductIndexer
{
public function indexProduct(int $productId): void
{
$product = \CIBlockElement::GetById($productId)->GetNext();
$prices = \CCatalogProduct::GetOptimalPrice($productId, 1, [], 'N', [], SITE_ID);
$props = $this->getProductProperties($productId);
$document = [
'id' => $productId,
'name' => $product['NAME'],
'description' => strip_tags($product['DETAIL_TEXT']),
'brand' => $props['BRAND']['VALUE'],
'price' => $prices['RESULT_PRICE']['DISCOUNT_PRICE'],
'in_stock' => $props['QUANTITY']['VALUE'] > 0,
'category' => $this->getCategoryPath($product['IBLOCK_SECTION_ID']),
];
$this->searchEngine->upsertDocument($document);
}
}
Синхронізація через чергу (\Bitrix\Main\Application::getInstance()->addBackgroundJob()) — зміни обробляються асинхронно, не сповільнюючи основний потік.
React-компонент пошуку
Instant search з debounce — основа UX. Мінімальний час затримки для відчуття живого відгуку: 200–300 мс.
function SearchBox() {
const [query, setQuery] = useState('');
const debouncedQuery = useDebounce(query, 250);
const { data, isLoading } = useQuery({
queryKey: ['search', debouncedQuery],
queryFn: () => searchProducts(debouncedQuery),
enabled: debouncedQuery.length >= 2,
staleTime: 10_000,
});
return (
<div className="search-wrapper">
<input
value={query}
onChange={e => setQuery(e.target.value)}
placeholder="Пошук товарів..."
/>
{debouncedQuery.length >= 2 && (
<SearchDropdown results={data} isLoading={isLoading} />
)}
</div>
);
}
Дропдаун пошуку розбивається за категоріями: «Товари», «Категорії», «Бренди», «Статті». Категоризація робиться на сервері або на фронті з єдиної відповіді.
Чому варто впроваджувати аналітику пошуку?
Пошукова аналітика — недооцінений інструмент. Запити з нульовими результатами прямо вказують на товари, яких немає, але які шукають. Запити з низьким CTR — на невідповідність очікуванням. Ми налаштовуємо click tracking в GA4 та власну таблицю local_search_analytics, що дозволяє точково правити ранжування.
Кейс з нашої практики: будівельний гіпермаркет
Магазин будматеріалів, 85 000 SKU, 12 000 унікальних пошукових запитів на добу. Проблема: штатний пошук Бітрікс не знаходив товари при помилках («шпатлёфка» замість «шпатлівка»), не підтримував пошук за артикулом, час відповіді — 800–1200 мс.
Вибрали Meilisearch (один сервер, синхронізація через чергу Бітрікс).
Реалізація: Індекс включає: назву, опис, бренд, артикул, синоніми (окрема таблиця в Бітрікс з парами «запит → правильний термін»). Fuzzy search з typoTolerance — Meilisearch автоматично обробляє помилки. В React-дропдауні — 4 секції: топ-4 товари, категорії (якщо запит збігається з назвою категорії), бренди, «Дивитися всі результати». Висота дропдауну фіксована (max 480px), всередині список з прокруткою.
| Метрика |
До |
Після |
| Час відповіді пошуку |
800–1200 мс |
35–80 мс |
| Zero-results rate |
18% |
4% |
| CTR з пошуку |
34% |
61% |
| Знаходження за артикулом |
Ні |
Так |
Повна сторінка результатів
Для повної сторінки результатів (/search/?q=шпатлівка) — React-застосунок з боковим фільтром (ті ж компоненти, що й у каталозі), сортуванням, пагінацією. URL синхронізується з усіма параметрами. Highlighting — підсвічування збігів у результатах пошуку. Meilisearch повертає поле _formatted з тегами <em>, які стилізуються в React.
Як проходить розробка пошуку на React?
- Аналіз каталогу: об'єм, структура інфоблоків, типові запити.
- Вибір двигуна та налаштування індексу з синонімами та стоп-словами.
- Синхронізація: написання індексатора, налаштування черг.
- Розробка React-компонентів: instant search, дропдаун, сторінка результатів.
- Інтеграція аналітики: click tracking, моніторинг zero-results.
- Тестування та оптимізація: A/B тести швидкості, коригування ранжування.
Що входить в роботу
- Вибір пошукового двигуна під об'єм і бюджет
- Налаштування індексу, синхронізація з каталогом Бітрікс
- Розробка React: instant search, дропдаун, повна сторінка результатів
- Налаштування синонімів, стоп-слів, boost-ранжування
- Аналітика: click tracking, zero-results моніторинг
- Документація, передача доступів, навчання команди
- Постпроектна підтримка: гарантія 3 місяці
Терміни та вартість
Вартість розраховується індивідуально після аудиту каталогу. Instant search з дропдауном — від 2 тижнів. Повна сторінка результатів + аналітика — ще від 2 тижнів. Пишіть — оцінимо ваш проект безкоштовно.
Гарантуємо: 10+ років досвіду з Бітрікс, сертифіковані спеціалісти, 15+ успішних впроваджень кастомного пошуку. Отримайте консультацію — напишіть нам.
Як React вирішує проблему повільного каталогу в Бітрікс?
Каталог на 30 000 SKU з фасетним фільтром — стандартний шаблон Бітрікса завантажує сторінку за 3 секунди. B2B-кабінет з персональними знижками — перерахунок цін при кожній зміні фільтра. Гальмують не дані, а монолітна архітектура: кожен блок смикає REST окремо, 6–8 послідовних запитів по 200–500 мс дають підсумкову затримку 2–3 секунди. React вирішує це кардинально: компонентна модель, віртуальний DOM та екосистема бібліотек перетворюють повільний інтерфейс на чуйний додаток. Ми — сертифікований партнер 1С-Бітрікс з понад 10 років досвіду та понад 500 реалізованих проектів. Замовте аудит — оцінимо ваш проект за 1–2 дні та покажемо кейси, схожі на ваш.
Архітектурні підходи
SPA на React + REST API Бітрікс (BX.rest)
React-додаток живе окремо, звертається до /rest/ або кастомних ендпоінтів. Максимум контролю, але й максимум роботи.
- Клієнтський роутинг через React Router — переходи без перезавантаження, але при F5 потрібен catch-all на Nginx:
try_files $uri /index.html
- Оптимістичні оновлення: кошик оновлюється миттєво,
sale.basket.update летить фоном. При помилці відкочуємо стейт і показуємо тост
- Фронтенд деплоїться на CDN незалежно від Бітрікса — оновили кнопку, не чіпаючи бекенд
SSR з гідратацією — коли Яндекс не бачить SPA
Яндекс навчився рендерити JS, але неідеально; Googlebot краще, але все одно не 100%. Серверний рендеринг React-компонентів через Node.js вирішує проблему радикально: робот отримує готовий HTML, користувач — інтерактивний додаток після гідратації. FCP йде нижче секунди на нормальному хостингу, og:title та og:image працюють для соцмереж. Складність — потрібен Node.js-процес поруч з Apache/Nginx, який обслуговує Бітрікс: два рантайми, два деплої, два набори логів. Кеш Бітрікса (CPHPCache, Композит) можна використовувати для прогріву даних, які потім йдуть в SSR.
Headless Бітрікс — адмінка для контент-менеджерів, React для відвідувачів
Контент-менеджер заходить у /bitrix/admin/, редагує інфоблоки. Відвідувач бачить React-додаток, який ходить за даними через API. Один бекенд обслуговує сайт, мобільний додаток та Telegram-бота. Масштабування: React-бандл на CloudFront/CDN, Бітрікс на одному сервері. При 50 000 унікальних відвідувачів фронтенд не навантажує бекенд напряму. Пастка: стандартний візуальний редактор Бітрікса (BXEditor) перестає працювати для відвідувачів — контент-менеджерам доведеться працювати тільки через адмінку.
Стек і компонентна архітектура
Стек, який реально використовуємо
| Технологія |
Для чого саме |
| 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 замість порожнього масиву. Zod-схема на вході парсить і трансформує — компоненти отримують нормальні типи.
// Реальний тип відповіді CIBlockElement через REST — сюрпризи всюди
interface BitrixProduct {
ID: string; // так, string, не number
ACTIVE: "Y" | "N"; // не boolean
PRICE: string; // теж string
QUANTITY: string; // і це string
}
Продуктивність та інтеграція з API
Як React покращує Core Web Vitals
Агрегуючі ендпоінти — база. Один ajax.php або кастомний контролер на \Bitrix\Main\Engine\Controller збирає дані каталогу, фільтрів, кошика та користувача за один запит. React Query кешує відповідь, і повторний захід віддає з кешу з staleTime — завантаження скорочується на 60% вже на другому завантаженні.
-
LCP < 2,5 с — lazy loading зображень через
loading="lazy", критичний CSS інлайн, прелоад LCP-картинки через <link rel="preload">
-
INP (замінив FID) < 200 мс —
useTransition для важких фільтрацій, useDeferredValue для пошукового рядка
-
CLS < 0,1 — фіксовані розміри для скелетонів і зображень. Skeleton-плейсхолдери замість спінерів
Віртуалізація — не опція, а необхідність. Каталог з фасетним фільтром може повернути 500 товарів на сторінку. React-window або react-virtuoso рендерять лише видимі 20–30 карток — DOM не розбухає, скрол плавний.
REST і кастомні контролери
З коробки через /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 — фронтенд запитує рівно ті поля, які потрібні. Економія трафіку на мобільних до 40%
Чому React, а не Vue чи шаблони Бітрікса?
- Екосистема. Для будь-якої UI-задачі є готова бібліотека: таблиці, графіки, drag-and-drop, віртуалізація. Для Vue вибір вужчий, для шаблонів Бітрікса — майже відсутній.
- Кадри. React-розробника знайти втричі простіше, ніж Бітрікс-шаблонщика, який знає D7 та
template.php.
- React Native. Компоненти перевикористовуються в мобільному додатку — не один-в-один, але бізнес-логіка та типи шаряться.
- Поетапне впровадження. Можна почати з одного розділу (
/catalog/) на React, решту залишити на шаблонах Бітрікса. component_epilog.php підключає React-бандл, дані прокидуються через window.__INITIAL_DATA__.
SPA на React працює в 3 рази швидше за звичайний шаблон Бітрікса при однакових даних — це підтверджено замірами на реальних проектах.
Проекти, терміни та що входить в роботу
Типові проекти, які ми вже зробили
- Інтернет-магазин на 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 тижнів |
- Аудит поточного коду Бітрікса та архітектури
- Проектування API-шару (REST / кастомні контролери / GraphQL)
- Розробка дизайн-системи та компонентів
- Налаштування CI/CD (деплой React-бандла незалежно від Бітрікса)
- Документація по ендпоінтах і типах (Swagger / TypeScript-типи)
- Передача доступів до сервера, адмінки, репозиторію
- Навчання контент-менеджерів роботі через адмінку
- Гарантійна підтримка 2 місяці після здачі
Точні цифри — після розбору ТЗ. Оцінка поетапна, з фіксованим бюджетом на кожен спринт. Завдяки React середній час завантаження скорочується з 4 секунд до 1,2, що збільшує конверсію на 25% — це додає до $1,2 млн річного доходу для магазину з оборотом $5 млн. Отримайте консультацію — ми підготуємо кейси, схожі на ваш проект.
Як ми впроваджуємо React на проекті
- Аудит існуючого коду — знаходимо вузькі місця: надлишкові запити, застарілі шаблони, неоптимальні кеші.
- Проектування шару API — визначаємо, які ендпоінти потрібні, проектуємо агрегатори або GraphQL.
- Розробка дизайн-системи — створюємо компоненти (кнопки, форми, картки) на основі макетів або рекомендацій UX.
- Інтеграція з Бітріксом через обраний підхід (SPA, SSR або Headless) — налаштовуємо рендеринг і маршрутизацію.
- Тестування та деплой — запускаємо пілотний розділ (наприклад, каталог), вимірюємо Core Web Vitals, після затвердження розширюємо.
Типові помилки при впровадженні React в Бітрікс:
- Ігнорування кешування Бітрікса — React Query може конфліктувати з композитним кешем, якщо не налаштувати теговане кешування.
- Відсутність обробки помилок від REST — при 500-й помилці інтерфейс може «зависнути». Потрібен глобальний обробник з fallback UI.
- Забагато мікро-компонентів — кожен маленький віджет смикає API. Краще агрегувати дані в одному запиті.
- Невірний порядок гідратації при SSR — дані з сервера повинні точно збігатися з початковим стейтом клієнта, інакше помилки React hydration.
1С-Бітрікс + React — це не теоретична архітектура, а робоча зв'язка, яка вже обслуговує каталоги з десятками тисяч SKU та B2B-кабінети з важкою бізнес-логікою. Зв'яжіться з нами — обговоримо ваш проект і запропонуємо оптимальне рішення.