Developing widgets 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

Widget Development for Bitrix24

A classic situation: CRM is already in use, managers are tracking all deals, but you need to add a block with data from an external system to the deal card — for example, warehouse stock from ERP or delivery status from a logistics company. This cannot be done with built-in tools; a widget is required via the REST API and the UI Extensions embedding mechanism.

Widgets in Bitrix24 are a distinct type of application that renders inside the portal interface through an iframe or JS SDK. Since 2022, Bitrix has been developing the UI Extensions concept as a replacement for classic iframe widgets. Let's break down what to use when, and how it is done in practice.

Widget Types and Embedding Locations

Bitrix24 supports several embedding mechanisms:

  • Placement API (BX24.placement.call) — the classic method: an application registers a placement, and Bitrix24 displays it in the appropriate location in the interface
  • UI Extensions — a set of ready-made components (Button, Dialog, Loader, Alert) available via @bitrix24/b24jssdk. They work inside an iframe but with access to the portal's event bus
  • Slider — opening an arbitrary URL in a side panel via BX24.openApplication()

Active placements are registered when the application is installed via the app.option.set method and are stored in the b_app_option table. Available embedding locations:

Placement Where It Appears
CRM_DEAL_DETAIL_TAB Tab on the deal card
CRM_LEAD_DETAIL_TAB Tab on the lead card
CRM_CONTACT_DETAIL_ACTIVITY Activity in the contact timeline
TASK_VIEW_TAB Tab in a task
CALL_CARD Call card
TELEPHONY_CALL_BEFORE_ANSWER Before answering a call
TOP_MENU_ITEM Top menu item

iframe Widget Architecture

A typical widget consists of two parts: a server-side handler (an endpoint that returns the HTML of the widget page) and client-side code inside the iframe.

Initialization in the client-side code:

BX24.init(() => {
    const placement = BX24.placement.info();
    // placement.options contains context: deal id, user id, etc.
    const dealId = placement.options.ID;

    BX24.callMethod('crm.deal.get', { id: dealId }, (result) => {
        if (result.error()) {
            console.error(result.error());
            return;
        }
        renderWidget(result.data());
    });
});

iframe height — a frequent issue. Bitrix24 does not make the iframe elastic automatically. After rendering content, you must explicitly call:

BX24.fitWindow(() => {
    // callback after height change
});

If this is not done, the widget will be clipped or an internal scrollbar will appear.

UI Extensions: The Modern Approach

Starting from portal version 2024+, using @bitrix24/b24jssdk is recommended. It provides typed access to the REST API directly from within the iframe:

import { initializeB24Frame, B24Frame } from '@bitrix24/b24jssdk';

const $b24 = await initializeB24Frame();
const profile = await $b24.fetchProfile();
const result = await $b24.callMethod('crm.deal.list', {
    filter: { ASSIGNED_BY_ID: profile.id },
    select: ['ID', 'TITLE', 'STAGE_ID']
});

The SDK handles authorization automatically (the OAuth token is passed via postMessage), so client_secret does not need to be stored on the client.

Placement Registration and Application Manifest

The application registers placements upon installation via the OnAppInstall hook. Example in the manifest:

{
  "placements": [
    {
      "placement": "CRM_DEAL_DETAIL_TAB",
      "handler": "https://myapp.example.com/widget/deal-tab",
      "title": "ERP Data",
      "description": "Stock and reservations for deal line items"
    }
  ]
}

Or programmatically via REST:

POST /rest/placement.bind
{
  "PLACEMENT": "CRM_DEAL_DETAIL_TAB",
  "HANDLER": "https://myapp.example.com/widget/deal-tab",
  "TITLE": "Warehouse"
}

Authorization and Security

All requests from the iframe to the server must pass the AUTH_ID (a short-lived token, 1 hour) or use REFRESH_TOKEN to renew it. Never store client_secret in client-side code — only on the server.

Validate the incoming event from postMessage:

window.addEventListener('message', (event) => {
    if (event.origin !== 'https://your-portal.bitrix24.ru') return;
    // processing
});

Common Challenges

CSP (Content Security Policy) — Bitrix24 restricts frame-ancestors. Your application domain must be whitelisted, which is configured automatically when publishing in the Marketplace or registering a local application.

Slow BX24.init() initialization — if the widget takes longer than 3 seconds to load, users switch to another tab. Optimization: load bx24.js via CDN, show a skeleton loader while waiting for data.

Cross-domain cookies — for session-based authentication with your own backend, use SameSite=None; Secure, otherwise the browser will block cookies inside the iframe.

Development Timeline

Widget Type Scope Timeline
Simple informational widget (CRM data read-only) S 1–2 days
Interactive widget with CRM write M 3–5 days
Widget with external system integration L 1–2 weeks
Widget suite (5+ placements) XL 2–4 weeks

The majority of the time is spent not on the widget itself, but on setting up OAuth authorization, handling edge cases (expired token, portal in a different data center), and testing across multiple browsers — Bitrix24 supports Chrome, Firefox, Safari, and mobile apps with varying iframe behavior.