Developing a search engine with autocomplete in Vue.js 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

Search with Autocomplete Development in Vue.js for 1C-Bitrix

The built-in Bitrix search (bitrix:search.title) does not support autocomplete out of the box. There are third-party full-text search solutions (Sphinx, Elasticsearch), but for most online stores the task is solved with a Vue component using debounced requests to the Bitrix search API.

Bitrix Search API

The Bitrix search module uses the b_search_content table (MySQL full-text index) or FULLTEXT indexes. A fast endpoint is needed for autocomplete:

class SearchController extends \Bitrix\Main\Engine\Controller
{
    public function suggestAction(string $query, int $limit = 8): array
    {
        if (mb_strlen($query) < 2) return ['items' => []];

        // Search via CSearch::Search or direct query to b_search_content
        $results = \CSearch::Search([
            'QUERY'    => $query . '*', // Prefix search
            'SITE_ID'  => SITE_ID,
            'MODULE'   => 'iblock',
            'PARAM2'   => $iblockId,
        ]);

        $items = [];
        while ($item = $results->Fetch()) {
            $items[] = [
                'title' => $item['TITLE'],
                'url'   => $item['URL'],
                'image' => $item['PARAM1'], // If configured
            ];
            if (count($items) >= $limit) break;
        }
        return ['items' => $items];
    }
}

SearchAutocomplete Component

<script setup>
import { ref, watch } from 'vue';
import { useDebounceFn } from '@vueuse/core';

const query = ref('');
const suggestions = ref([]);
const isOpen = ref(false);

const fetchSuggestions = useDebounceFn(async (q) => {
    if (q.length < 2) { suggestions.value = []; return; }
    const { data } = await api.get('/search/suggest', { params: { query: q } });
    suggestions.value = data.items;
    isOpen.value = data.items.length > 0;
}, 300);

watch(query, fetchSuggestions);
</script>

UX Details That Matter

Keyboard navigation — arrow keys up/down through the list, Enter to navigate, Escape to close. Implemented via keydown handlers and an activeIndex ref.

Match highlighting — highlight the part of the product name matching the query:

function highlight(text, query) {
    const regex = new RegExp(`(${escapeRegex(query)})`, 'gi');
    return text.replace(regex, '<mark>$1</mark>');
}

Grouped results — display separately: products, categories, blog articles. Three parallel requests or one endpoint returning grouped JSON.

Search history — last 5 queries from localStorage. Shown on focus when the field is empty.

Integration with Elasticsearch / MeiliSearch

If the catalog is large (100,000+ items) and Bitrix search is slow — autocomplete queries an external search engine:

  • MeiliSearch — easy to set up, fast, open source
  • Elasticsearch — more powerful, more complex, suited for enterprise

Indexing Bitrix products in MeiliSearch — via an agent that synchronizes data when b_iblock_element changes.

Real-World Case

A pharmacy chain: search by INN, trade names, and manufacturers — 15,000 items. Bitrix search produced irrelevant results (did not account for synonyms and typos). Solution: MeiliSearch with configured synonyms (e.g., "aspirin" → "acetylsalicylic acid"), Vue component with 250 ms debounce. Autocomplete response time — 30–80 ms. The built-in Bitrix search was kept for the full results page.

Delivery Timelines

Option Timeline
Autocomplete on Bitrix search 3 to 5 business days
With result grouping and highlighting 5 to 8 business days
With MeiliSearch/Elasticsearch integration 8 to 15 business days