Developing Embedded Applications with Vue.js for Bitrix24

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

Developing Embedded Applications on Vue.js for Bitrix24

Embedded applications in Bitrix24 are standalone frontend modules that load inside the portal interface via iframe or the BX24 JS SDK. The standard approach is a PHP page with window.BX24.init() and jQuery code. When the application logic becomes non-trivial — multiple screens, state management, reactive updates — jQuery turns into unmaintainable spaghetti. Vue.js solves this problem architecturally.

How Applications Are Embedded in Bitrix24

Bitrix24 provides two placement mechanisms:

  • iframe application — loaded from an external URL in the portal window. Exchanges data with Bitrix24 through the window.BX24 JS library.
  • Embedded JS application — hosted on the same domain, registered via \Bitrix\Rest\AppTable, uses the server REST API directly.

For Vue applications, the standard choice is an iframe with separate hosting or placement in /local/apps/. The server-side can be written in Laravel, Node.js, or Bitrix itself.

Initializing Vue Inside Bitrix24

Connecting the BX24 SDK and starting the Vue application:

<!-- index.html -->
<script src="//{{portal}}.bitrix24.ru/bitrix/js/rest/bx24/bx24.js"></script>
<div id="app"></div>
<script type="module" src="/assets/app.js"></script>
// main.js
import { createApp } from 'vue'
import App from './App.vue'

window.BX24.init(() => {
  const app = createApp(App)
  app.provide('bx24', window.BX24)
  app.mount('#app')
})

Passing BX24 via provide/inject allows it to be used in any component without global variables.

Working with the Bitrix24 REST API from Vue

For REST calls, BX24.callMethod or BX24.callBatch is used. Wrapping them in promises:

// composables/useBx24.js
import { inject } from 'vue'

export function useBx24() {
  const bx24 = inject('bx24')

  function callMethod(method, params = {}) {
    return new Promise((resolve, reject) => {
      bx24.callMethod(method, params, (result) => {
        if (result.error()) reject(result.error())
        else resolve(result.data())
      })
    })
  }

  async function callBatch(calls) {
    return new Promise((resolve, reject) => {
      bx24.callBatch(calls, (results) => {
        const errors = Object.values(results).filter(r => r.error())
        if (errors.length) reject(errors[0].error())
        else resolve(Object.fromEntries(
          Object.entries(results).map(([k, v]) => [k, v.data()])
        ))
      })
    })
  }

  return { callMethod, callBatch }
}

A typical deals list component:

<script setup>
import { ref, onMounted } from 'vue'
import { useBx24 } from '@/composables/useBx24'

const { callMethod } = useBx24()
const deals = ref([])
const loading = ref(true)

onMounted(async () => {
  deals.value = await callMethod('crm.deal.list', {
    select: ['ID', 'TITLE', 'STAGE_ID', 'OPPORTUNITY'],
    filter: { STAGE_ID: 'NEW' },
    order: { DATE_CREATE: 'DESC' }
  })
  loading.value = false
})
</script>

Managing iframe Size

Bitrix24 does not manage iframe height automatically. The application must report its own size:

// App.vue
import { onMounted, onUpdated } from 'vue'

const bx24 = inject('bx24')

function fitWindow() {
  bx24.fitWindow()
}

onMounted(fitWindow)
onUpdated(fitWindow)

For dynamic applications with variable height — a ResizeObserver on the root element calling bx24.resizeWindow(width, height).

Authorization and Access Rights

The access token is passed automatically via the BX24 SDK. For server-side requests, bx24.getAuth() is used:

const auth = bx24.getAuth()
// { access_token, expires_in, scope, domain, ... }

await fetch('/api/my-endpoint', {
  headers: { Authorization: `Bearer ${auth.access_token}` }
})

Checking user permissions — crm.contact.access.has and similar methods depending on the entity.

Build and Deployment

Vite is the optimal build choice:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  base: '/local/apps/my-app/',
  build: {
    outDir: 'dist',
    assetsDir: 'assets',
  }
})

The built dist/ is placed on the server. The entry point URL is specified in the Bitrix24 application settings. For local development, ngrok or a Vite dev server with HTTPS is used — Bitrix24 requires HTTPS for iframe applications.

Typical Use Cases

Deals dashboard — aggregating CRM data, visualizing the funnel, filtering by responsible persons and periods. Standard Bitrix24 reports are insufficient for custom data slices.

Custom lead creation form — a multi-step form with validation, dependent fields, and file uploads. The standard CRM card does not support complex conditional field display logic.

Integration connector — the application retrieves data from an external system (1C, ERP, marketplace) and displays it in the Bitrix24 context with synchronization capability.

Task planner — a custom UI for managing tasks with drag-and-drop, a kanban board, or a timeline view on top of the standard tasks API.

Timeline

A simple application (one screen, CRUD for a single entity) — 2–3 business days. An application with multiple screens, authorization, a server-side component, and deployment — 1–2 weeks depending on the complexity of the business logic.