Developing a product filter using 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

Product Filter Development with Vue.js for 1C-Bitrix

The standard Bitrix AJAX filter (bitrix:catalog.smart.filter) works by reforming the URL and fully re-rendering the section on the server. With 30+ filterable properties and a large catalog, every change causes a noticeable delay. A Vue filter delivers an instant UI with smart debouncing of server requests.

Data Sources for the Faceted Filter

Bitrix stores facets in the b_catalog_facet_index* tables — the same ones used by the smart filter. For the Vue filter, we use the same mechanism via D7:

use Bitrix\Catalog\v2\Facade\Catalog;

// Retrieve facet data via the smart filter API
$filterFacets = \CCatalogSmartFilter::GetFacets($iblockId, $currentFilter);

This is faster than counting manually via GetList, because the b_catalog_facet_index_* index is already pre-calculated.

Filter State Architecture

Pinia store for the filter:

export const useFilterStore = defineStore('filter', {
    state: () => ({
        selectedValues: {},   // { propertyCode: [val1, val2] }
        facets: {},           // Available values with match counts
        priceRange: { min: 0, max: 999999 },
        isLoading: false,
    }),
    actions: {
        async applyFilter() {
            this.isLoading = true;
            // POST /api/catalog/filter with selectedValues
            // Returns: items, facets (updated), pagination
        }
    }
});

Filter Widget Types

  • Checkboxes — for list-type properties (color, brand, material)
  • Price range — a slider with two handles, input type="range" or a custom component
  • Radio buttons — for mutually exclusive values (condition: new/used)
  • Category tree — a recursive component for tree-structured sections
  • Search within filter — for long brand lists (100+ values)

URL Synchronization

The filter must synchronize its state with the URL — to allow sharing links and for correct browser Back button behavior:

import { useRoute, useRouter } from 'vue-router';

// On filter change:
router.push({ query: buildQueryFromFilter(filterStore.selectedValues) });

// On initialization:
filterStore.initFromQuery(route.query);

Real-World Case

A clothing marketplace: filtering by size, color (50+ colors), brand (200+ brands), material, and price. The standard Bitrix smart filter generated URLs like ?arrFILTER_SIZE[]=S&arrFILTER_SIZE[]=M&... over 500 characters long and reloaded the entire page. A Vue filter with URL serialization using shortened keys and a 400 ms debounce: changes do not cause a page reload, facets update asynchronously, and checkboxes with 0 matches are not grayed out. Response time — 200–600 ms depending on query complexity.

Delivery Timelines

Option Timeline
Basic filter (checkboxes, price) 4 to 7 business days
With facets, category tree, and URL sync 8 to 12 business days
Integration with an existing Vue catalog 3 to 5 additional business days