Integration of Vue.js with 1C-Bitrix website template

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
    1173
  • 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
    745
  • 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

Integrating Vue.js with a 1C-Bitrix Site Template

The main challenge of integrating Vue into a Bitrix template is the conflict between the global state of jQuery plugins — which Bitrix uses extensively — and Vue's reactivity system. There is also the issue of script loading order, which Bitrix controls through its own asset manager.

Connecting Vue to the Template Without Conflicts

In the header.php of the Bitrix template, add Vue as a module via the asset manager:

\Bitrix\Main\Page\Asset::getInstance()->addJs('/local/templates/main/vue-dist/app.js', true);

The true flag moves the script to the end of <body>, which is important for Vue since it requires the DOM to be ready.

An alternative is BX.ready(), Bitrix's wrapper around DOMContentLoaded:

BX.ready(function() {
    const { createApp } = Vue;
    createApp(App).mount('#vue-app');
});

Mount Points in the Template

In Bitrix template files (.php), place div containers for Vue widgets:

// In header.php or wherever needed on the page
<div id="vue-search-widget" data-catalog-id="<?= $catalogId ?>"></div>

The Vue application reads attributes via el.dataset:

const el = document.getElementById('vue-search-widget');
const catalogId = el.dataset.catalogId;
createApp(SearchWidget, { catalogId }).mount(el);

Passing the CSRF Token

Bitrix generates a CSRF token to protect forms. When making AJAX requests from Vue, it must be included:

// Retrieve the token from a cookie (Bitrix stores it in bitrix_sessid)
function getBitrixToken() {
    return document.querySelector('input[name="sessid"]')?.value
        || BX.bitrix_sessid?.();
}

// In the axios config:
axios.defaults.headers.common['X-Bitrix-Csrf-Token'] = getBitrixToken();

Conflict with jQuery and BX.UI

Bitrix uses window.BX — its own namespace with utilities — alongside jQuery. Vue does not directly conflict with them, but:

  • Do not use jQuery to manipulate the DOM inside Vue components — Vue loses reactivity
  • BX.UI.Dialog, BX.PopupWindow — can be called from Vue via onMounted/events, but not from the template

Real-World Case

A corporate website on Bitrix: a Vue product-selection widget was added to the template. The widget worked, but after a Bitrix modal window (BX.PopupWindow) was opened, Vue's reactivity broke — the popup cloned the DOM element of the mount point. The solution: mounting the Vue widget to document.body via teleport, rather than inside the element that could be cloned.

Delivery Timelines

Integrating Vue into an existing template with one or two widgets — 4 to 8 hours.