Developing a React search engine for 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

React Search Development for 1C-Bitrix

The standard Bitrix search works through the search module with a morphological index in the b_search_content and b_search_stem tables. The standard bitrix:search.title component redirects to a results page that is server-rendered. For a simple informational site this is acceptable. For an online store with live search (instant search, suggestions as you type, filtering directly in the dropdown) — the standard approach is architecturally unsuitable.

A React search means a dedicated index (Elasticsearch/OpenSearch or custom SQL) combined with a React interface featuring debounce, categorized results, and click analytics.

Choosing a Search Engine

Elasticsearch / OpenSearch — justified when the volume exceeds 100,000 documents and you need full-text search with morphology, boost ranking, and synonyms. Requires a dedicated server.

Typesense — a simpler alternative with good performance and easier administration. Suitable for mid-size catalogs.

Meilisearch — fast to get started, fuzzy search out of the box, solid documentation. Suitable for catalogs up to 500,000 products.

Custom SQL (Bitrix)FULLTEXT INDEX in MySQL or tsvector in PostgreSQL. Works without additional infrastructure; sufficient for catalogs up to 50,000 SKUs.

For most mid-size online stores (up to 100,000 SKUs) the recommendation is Meilisearch or custom PostgreSQL full-text. Elasticsearch only if the infrastructure already exists or complex search analytics are required.

Indexing Bitrix Products

Regardless of the chosen engine, you need data synchronization between Bitrix and the search index.

// Event handler for product updates
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
    'catalog', 'OnProductUpdate',
    function(\Bitrix\Main\Event $event) {
        $productId = $event->getParameter('id');
        \Local\Search\IndexQueue::add($productId, 'update');
    }
);

// Indexer (runs via 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);
    }
}

Synchronization via a queue (\Bitrix\Main\Application::getInstance()->addBackgroundJob()) — changes are processed asynchronously without slowing down the main request.

React Search Component

Instant search with debounce is the foundation of the UX. Minimum delay for a live-response feel: 200–300 ms.

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="Search products..."
      />
      {debouncedQuery.length >= 2 && (
        <SearchDropdown results={data} isLoading={isLoading} />
      )}
    </div>
  );
}

The search dropdown is divided into categories: "Products," "Categories," "Brands," "Articles." Categorization is done server-side or client-side from a single response.

Case Study: Building Supplies Hypermarket Search

Building materials store, 85,000 SKUs, 12,000 unique search queries per day. Problem: the standard Bitrix search did not find products with typos ("shpatlofka" instead of "shpatlevka"), did not support search by article number, and response time was 800–1,200 ms.

Meilisearch was chosen (single server, synchronization via Bitrix queue).

Implementation:

The index includes: name, description, brand, article number, synonyms (a separate Bitrix table with "query → correct term" pairs). Fuzzy search with typoTolerance — Meilisearch handles typos automatically.

The React dropdown has 4 sections: top 4 products, categories (if the query matches a category name), brands, and "View all results." The dropdown height is fixed (max 480 px) with an internal scrollable list.

Click analytics: when a search result is clicked, an event is sent to GA4 and to a local local_search_analytics table — what was searched, what was found, what was clicked. Data is used for manual boost ranking adjustments (popular products are ranked higher).

Metric Before After
Search response time 800–1200 ms 35–80 ms
Zero-results rate 18% 4%
Search CTR 34% 61%
Results by article number No Yes

Full Results Page

For the full results page (/search/?q=shpatlevka) — a React application with a sidebar filter (the same components as in the catalog), sorting, and pagination. The URL is synchronized with all parameters.

Highlighting — matching terms are highlighted in search results. Meilisearch returns a _formatted field with <em> tags that are styled in React.

Search Analytics

Search analytics is an underutilized tool. Queries with zero results directly indicate products that are wanted but not stocked. Queries with low CTR point to expectation mismatches.

Minimum metric set: top queries, zero-results queries, CTR per query, conversion from search. All of this is built on GA4 events plus a custom analytics table.

Scope of Work

  • Selecting a search engine appropriate for the volume and budget
  • Index setup, synchronization with the Bitrix catalog
  • React development: instant search, dropdown, full results page
  • Configuring synonyms, stop words, boost ranking
  • Analytics: click tracking, zero-results monitoring

Timeline: instant search with dropdown — 2–3 weeks. Full results page + analytics — another 2–3 weeks.