Development of custom CRM cards 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

Development of Custom CRM Cards in Bitrix24

The standard deal card in Bitrix24 is a universal interface for all industries at once. As a result, an equipment sales manager sees the same fields as a rental manager. Fields aren't grouped by meaning, calculated values are absent, conditional logic for display is missing. A custom card solves a specific task: show the manager exactly what they need at the current work stage.

Two Levels of Customization

Bitrix24 offers two ways to change a CRM entity card, and they differ fundamentally in depth.

Level 1: Customization through the interface. In a deal card (contact, smart-process) click "Configure card" → "Configure fields and sections". Here you can:

  • Rename sections
  • Drag fields between sections
  • Hide unnecessary fields
  • Set field requirements by stages (for deals)

This is free and covers ~40% of requests. But you can't: add calculated fields, conditional logic, custom widgets, data from external systems.

Level 2: Development through REST Placement API. This is embedding arbitrary HTML/JS content into specific card zones. Here's where real customization begins.

Placement API: Embedding Points

A CRM entity card contains several zones (placements) where you can embed custom content:

  • CRM_DEAL_DETAIL_TAB — tab in deal card. Full area for any UI.
  • CRM_DEAL_DETAIL_ACTIVITY — block in timeline. Good for custom actions.
  • CRM_CONTACT_DETAIL_TAB, CRM_COMPANY_DETAIL_TAB — same for contacts and companies.
  • CRM_DYNAMIC_ITEM_DETAIL_TAB — tab in smart-process card.

Placement registration via REST:

BX24.callMethod('placement.bind', {
    PLACEMENT: 'CRM_DEAL_DETAIL_TAB',
    HANDLER: 'https://your-app.com/deal-tab.html',
    TITLE: 'Margin Calculator'
});

After registration, a new tab appears in the card. When opened, Bitrix24 loads the HANDLER in an iframe and passes context: ENTITY_ID (deal ID), AUTH_ID, REFRESH_ID.

Deep Dive: Custom Tab with Data

Consider a typical use case — a "Finance" tab in a deal card showing: sum by product items, cost from external 1C, margin, payment history.

Step 1: Get deal data

BX24.init(function() {
    var dealId = BX24.placement.info().options.ID;

    BX24.callBatch({
        deal: ['crm.deal.get', {id: dealId}],
        products: ['crm.deal.productrows.get', {id: dealId}]
    }, function(result) {
        var deal = result.deal.data();
        var products = result.products.data();
        renderFinanceTab(deal, products);
    });
});

Step 2: Request cost from external API. The tab makes a request to your backend, passing product SKUs. The backend proxies the request to 1C or ERP and returns the cost.

Step 3: Render. Calculate margin on the client and display the table. For visual match use CSS variables from B24 or the @bitrix24/b24-ui library.

Conditional Field Display Logic

Frequent request: hide/show fields depending on another field's value. For example, "Reason for Refusal" visible only at "Failed" stage. Standard functionality allows making a field required by stage, but not hiding it.

Solution — custom handler through placement CRM_DEAL_DETAIL_TAB or embedding JS code through custom field type. In the on-premise version you can modify template of component bitrix:crm.deal.detail with JS logic in script.js.

For cloud version the only clean way is placement with full redraw of needed field section. This means: you fetch data via REST, render fields with conditional logic in your iframe, and on save send changes back via crm.deal.update.

Widgets in Timeline

Placement CRM_*_DETAIL_ACTIVITY embeds a block right in the activity feed of the card. Suitable for:

  • Displaying delivery status (data from delivery company API)
  • Showing client balance from accounting system
  • Displaying latest tickets from helpdesk

The widget refreshes each time the card opens. For caching use BX24.appOption — app storage on B24 side.

Performance

Iframe tabs load on activation (click the tab). For heavy tabs this is normal — user doesn't wait for loading what they didn't open. But if you embed a widget in the main card area — it loads immediately. Each REST request from iframe — a network round-trip. Use BX24.callBatch to combine requests: one batch instead of five sequential calls.

Card Element Customization Method Timeframe
Regroup fields UI Configuration 1–2 hours
Required by stage UI Configuration 30 minutes
Custom tab with external data REST Placement 3–5 days
Conditional field logic (cloud) REST Placement + custom render 5–7 days
Timeline widget REST Placement Activity 2–3 days

Cloud Version Limitations

In the cloud you can't modify standard card sections — only add new tabs and widgets. You can't remove standard fields from main view (only hide them through card settings). For full control over card interface — on-premise version with overriding template of component crm.deal.detail.