REST-застосунки Бітрікс24 на TypeScript під ключ

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Послуги, які ми пропонуємо
Показано 1 з 1Усі 1626 послуг
REST-застосунки Бітрікс24 на TypeScript під ключ
Середній
~1-2 тижні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1357
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    944
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    693
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    829
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    731
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    1074

Проблема: відсутність типів у BX24 SDK

Офіційного TypeScript-пакету для BX24 SDK немає. Методи crm.deal.list, tasks.task.add, im.message.send працюють як чорний ящик — без підказок IDE. Розробник змушений постійно перемикатися на документацію, а в рантаймі ловити undefined через невірне поле. Ми вирішили цю проблему для 50+ проектів: типізуємо BX24 SDK, обгортаємо callMethod та callBatch, впроваджуємо React-віджети. Гарантія на код — 1 рік.

Типізація скорочує кількість помилок на етапі розробки вдвічі порівняно з чистим JavaScript. Один проект на TypeScript економить до 40% часу на налагодження та підтримку, що знижує витрати на підтримку до 30%. Стек: TypeScript, React, Node.js, MySQL.

Чому TypeScript для REST-застосунків Бітрікс24?

TypeScript усуває головний біль: автодоповнення в IDE. Більше не потрібно пам'ятати назви полів — редактор підкаже структуру BX24Deal, BX24Task або BX24CallResult. Вдвічі менше помилок на етапі розробки порівняно з чистим JavaScript. Ми використовуємо суворий режим з перевіркою strict: true. Це дає гарантію, що код не зламається через невірний тип.

Архітектура REST-застосунку Бітрікс24

Три типи застосунків в екосистемі Бітрікс24:

  • Веб-застосунок (iframe) — завантажується всередині інтерфейсу Бітрікс24 в iframe. JavaScript/TypeScript з доступом до BX24.js SDK.
  • Серверний застосунок — PHP/Node.js, працює незалежно, обмінюється з Бітрікс24 через REST поверх OAuth.
  • Віджет — компактний застосунок у sidebar або CRM.

TypeScript застосовний у всіх трьох випадках, але з різними точками входу.

Тип Складність розробки Типізація Продуктивність
Веб-застосунок (iframe) Середня Повна (TS у клієнті) Висока (локальний рендеринг)
Серверний (Node.js) Висока Повна (TS на сервері) Середня (залежить від API)
Віджет Низька Часткова (обмежений SDK) Висока

TypeScript краще за JavaScript для iframe та серверних застосунків: статична перевірка типів знижує баги на 30–50%. Для віджетів типізація менш критична, але ми все одно додаємо базові типи.

Типізація BX24 SDK

Офіційного TypeScript-пакету для BX24 SDK немає. Пишемо декларацію:

// types/bx24.d.ts
declare global {
    const BX24: {
        init(callback: () => void): void;
        isAdmin(): boolean;
        getAuth(): BX24Auth;
        refreshAuth(callback: (auth: BX24Auth) => void): void;
        callMethod(
            method:   string,
            params?:  Record<string, unknown>,
            callback?: (result: BX24CallResult) => void
        ): void;
        callBatch(
            calls:    Record<string, [string, Record<string, unknown>?]>,
            callback: (result: Record<string, BX24CallResult>) => void,
            bHaltOnError?: boolean
        ): void;
        resizeWindow(width: number, height: number): void;
        closeApplication(): void;
        placement: {
            info(): BX24PlacementInfo;
            call(command: string, params?: Record<string, unknown>): void;
        };
    };
}

interface BX24Auth {
    access_token:  string;
    refresh_token: string;
    expires_in:    number;
    domain:        string;
    member_id:     string;
}

interface BX24CallResult {
    status():  number;
    data():    unknown;
    error():   string | false;
    more():    boolean;
    next():    void;
    total():   number;
}

interface BX24PlacementInfo {
    placement: string;
    options:   Record<string, string>;
}

export {};

Типи для CRM-даних

// types/crm.ts

export interface BX24Deal {
    ID:                     string;
    TITLE:                  string;
    STAGE_ID:               string;
    OPPORTUNITY:            string;
    CURRENCY_ID:            string;
    ASSIGNED_BY_ID:         string;
    DATE_CREATE:            string;
    DATE_MODIFY:            string;
    CONTACT_ID:             string | null;
    COMPANY_ID:             string | null;
    COMMENTS:               string | null;
    UF_CRM_CUSTOM_FIELD?:   string;
    [key: string]: unknown;
}

export interface BX24Contact {
    ID: string;
    NAME: string;
    LAST_NAME: string;
    PHONE: Array<{ VALUE: string; VALUE_TYPE: string }>;
    EMAIL: Array<{ VALUE: string; VALUE_TYPE: string }>;
}

export interface BX24Activity {
    ID: string;
    SUBJECT: string;
    OWNER_ID: string;
    OWNER_TYPE_ID: string;
    CREATED: string;
}

export type StageId =
    | 'NEW' | 'PREPARATION' | 'PREPAYMENT_INVOICE'
    | 'EXECUTING' | 'FINAL_INVOICE' | 'WON' | 'LOSE';

export type AppType = 'iframe' | 'server' | 'widget';

Як типізувати callMethod з автоматичною пагінацією?

Проста обгортка з повним контролем типів:

// api/bx24client.ts

export function callMethod<T>(
    method: string,
    params: Record<string, unknown> = {}
): Promise<T[]> {
    return new Promise((resolve, reject) => {
        const results: T[] = [];

        const handleResult = (result: ReturnType<typeof BX24.callMethod extends (...args: unknown[]) => infer R ? R : never>) => {
            if (result.error()) {
                reject(new Error(String(result.error())));
                return;
            }

            const data = result.data() as T[];
            results.push(...(Array.isArray(data) ? data : [data as T]));

            if (result.more()) {
                result.next();
            } else {
                resolve(results);
            }
        };

        BX24.callMethod(method, params, handleResult);
    });
}

// Використання
import type { BX24Deal } from '@/types/crm';

const deals = await callMethod<BX24Deal>('crm.deal.list', {
    filter: { STAGE_ID: 'NEW' },
    select: ['ID', 'TITLE', 'OPPORTUNITY', 'ASSIGNED_BY_ID'],
    order:  { DATE_CREATE: 'DESC' },
});

result.more() + result.next() — механізм пагінації BX24 SDK. Обгортка автоматично обходить всі сторінки та повертає повний масив. Це знижує навантаження на розробника та гарантує, що ми не пропустимо дані.

Batch-запити для продуктивності

Кожен callMethod — окремий HTTP-запит. Для застосунків з високим навантаженням на API — використовуємо callBatch:

export function callBatch<T extends Record<string, unknown>>(
    calls: Record<string, [string, Record<string, unknown>?]>
): Promise<T> {
    return new Promise((resolve, reject) => {
        BX24.callBatch(calls, (results) => {
            const output = {} as T;
            let hasError = false;

            for (const [key, result] of Object.entries(results)) {
                if (result.error()) {
                    hasError = true;
                    console.error(`Batch error for "${key}":`, result.error());
                } else {
                    (output as Record<string, unknown>)[key] = result.data();
                }
            }

            if (hasError) reject(new Error('Batch had errors'));
            else resolve(output);
        });
    });
}

// Завантаження угоди з пов'язаними даними за один запит
const data = await callBatch<{
    deal:    BX24Deal;
    contact: BX24Contact;
    history: BX24Activity[];
}>({
    deal:    ['crm.deal.get',     { id: dealId }],
    contact: ['crm.contact.get',  { id: contactId }],
    history: ['crm.activity.list', { filter: { OWNER_ID: dealId, OWNER_TYPE_ID: '2' } }],
});

Batch-запити скорочують час завантаження інтерфейсу в 3–5 разів порівняно з послідовними викликами. На одному з проектів для рітейлера ми знизили час відкриття картки угоди з 8 до 1.5 секунд.

React + TypeScript застосунок в iframe Бітрікс24

// main.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './App';

BX24.init(() => {
    const container = document.getElementById('app');
    if (!container) return;

    const root = createRoot(container);
    root.render(<App />);

    const resizeObserver = new ResizeObserver(() => {
        BX24.resizeWindow(
            document.body.scrollWidth,
            document.body.scrollHeight
        );
    });
    resizeObserver.observe(document.body);
});

Процес роботи

  1. Аналітика — вивчаємо бізнес-логіку, виявляємо сутності CRM, визначаємо частоту запитів до API.
  2. Проектування — створюємо типи для BX24 SDK та всіх CRM-сутностей, плануємо batch-запити.
  3. Розробка — пишемо обгортки callMethod та callBatch, React-компоненти, налаштовуємо OAuth-авторизацію.
  4. Тестування — перевіряємо типи, пагінацію, обробку помилок, продуктивність batch.
  5. Деплой — розміщуємо застосунок у Бітрікс24, налаштовуємо права доступу, документуємо API.

Що входить в роботу

  • Повна типізація BX24 SDK та використовуваних CRM-сутностей.
  • Автоматична пагінація обгорток callMethod.
  • Batch-оптимізація для високонавантажених запитів.
  • React-компоненти з адаптивною версткою під iframe.
  • Документація з інтеграції та API.
  • Підтримка протягом 1 року.

Типові помилки та чек-лист

Часта помилка: забули обробити more() у пагінації Без автоматичного обходу сторінок отримаєте лише перші 50 записів. Наша обгортка вирішує це.
  • Неправильні типи для BX24.getAuth(): поля, що повертаються, можуть бути відсутні при першому виклику — використовуємо Partial<BX24Auth>.
  • Відсутність таймаутів для callMethod: при великій кількості запитів API може скинути з'єднання — ми додаємо повторні спроби.
  • Неповні типи користувацьких полів: UF_* поля потрібно описувати вручну, інакше вони залишаться any.

Терміни

Задача Терміни
Налаштування TypeScript, типи BX24 SDK та CRM-сутностей 1–2 дні
Простий iframe-застосунок (перегляд/редагування даних CRM) 3–5 днів
Повнофункціональний React-застосунок у Бітрікс24 2–4 тижні
Серверний Node.js/TypeScript застосунок з OAuth 1–2 тижні

Ми працюємо з REST API Бітрікс24 більше 5 років. Оцінимо ваш проект за 2 дні. Зв'яжіться з нами — отримайте консультацію та комерційну пропозицію без зобов'язань. Замовте розробку вашого REST-застосунку вже сьогодні.

Чому верстка сайтів на 1С-Бітрікс вимагає професіоналізму?

Відкриваєте template.php у попереднього підрядника — а там SQL-запити, бізнес-логіка та inline-стилі в одному файлі. На кожному другому проєкті, який ми беремо на підтримку, код шаблонів виглядає як звалище: кеш не працює, додати нову фічу — переписуй все. Виправлення такої верстки може коштувати чимало, а втрачений виторг через зламаний кошик у пік сезону може сягати десятків тисяч гривень.

Ми — команда сертифікованих розробників 1С-Бітрікс із десятирічним досвідом. За нашими плечима понад 50 успішних проектів верстки та підтримки. Наш підхід строго розділяє: логіка — в result_modifier.php або component_epilog.php, представлення — в template.php. Жодного CIBlockElement::GetList в шаблоні. Це скорочує час правок на 30–40% та виключає типові помилки, які ламають кеш. Подібну проблему виправляли клієнту з інтернет-магазину — він місяць не міг оновити блок «Акції». Після налаштування тегованого кеша правки вставали за хвилину, а не за день.

Отримайте безкоштовний аудит вашого проекту — зв'яжіться з нами.

Як правильно організувати шаблони компонентів?

Кастомний шаблон — це не один файл, а структура з п’яти-шести файлів:

  • template.php — тільки HTML та виведення $arResult
  • result_modifier.php — підготовка даних, додаткові вибірки
  • component_epilog.php — код після кешування (лічильники, динаміка)
  • style.css та script.js — підключаються через Asset::getInstance()->addCss() та addJs() (не через <link> — інакше ламається об'єднання)
  • .parameters.php — параметри візуального редактора

Приклад структури для каталогу:

local/templates/your_template/components/bitrix/catalog.section/.default/
├── template.php
├── result_modifier.php
├── component_epilog.php
├── style.css
├── script.js
└── .parameters.php

Типові шаблони, які верстаємо під ключ:

Компонент Що робимо
catalog.section та catalog.element Перемикання вигляду (плитка/список/таблиця), lazy load для зображень, srcset для ретини
sale.basket.basket AJAX-оновлення без перезавантаження, міні-кошик через sale.basket.basket.line
menu Мегаменю з кешуванням за розділами, відкладене завантаження підменю
search.title Автопідказки з дебаунсом 300 мс, прев'ю товарів у дропдауні
breadcrumb Мікророзмітка BreadcrumbList за Schema.org

Кешування: чому воно ламається і як лагодимо?

Компонентне кешування в Бітрікс ламається однією помилкою: вивели ім'я користувача всередині кешованого каталогу — всі бачать одне ім'я. Рішення — component_epilog.php для динамічних вставок.

Tagged cache ($this->setResultCacheKeys, CIBlock::clearIblockTagCache) налаштовуємо обов'язково. Змінили товар — очищується кеш лише цього товару, а не всього розділу. На проєкті з 50 000 товарів це дає приріст швидкості на 40% — в 1.4 раза швидше порівняно з повним скиданням.

Реальний кейс. Наш клієнт скаржився — на сторінці каталогу у всіх один кошик. Виявилося, попередній розробник вивів $_SESSION['BASKET'] всередині template.php компонента catalog.section. Компонент кешувався на годину — кошик застиг. Перенесли виведення в component_epilog.php, налаштували тегований кеш на sale.basket.basket.line. Сторінка не втратила у швидкості, кошик став актуальним. Збитки від несправного кошика в пік сезону могли бути значними, а вартість виправлення — помірною.

CSS-підходи: BEM, Tailwind або гібрид?

Для великих проєктів (30+ шаблонів) використовуємо BEM.product-card__price, .product-card--featured. Стилі ізольовані, конфліктів немає. У Бітрікс обгортки з класами bx-component не чіпаємо — обгортаємо свій BEM-блок всередині.

Для типових завдань (лендінги, адмінки) беремо Tailwind 3+ з PurgeCSS — підсумковий CSS 10–30 КБ замість сотень. Дизайн-токени в tailwind.config.js фіксують кольори, шрифти, відступи в одному місці.

На більшості проєктів застосовуємо гібрид: BEM для структурних компонентів (каталог, картка, чекаут), Tailwind для утилітарних речей (відступи, flex-розкладки). Межу обговорюємо з командою заздалегідь.

Як досягти Core Web Vitals при верстці сайтів на Бітрікс?

Critical CSS — виділяємо стилі першого екрану через пакет critical, інлайнимо в <head>. Решта завантажується асинхронно через media="print" onload="this.media='all'". LCP на мобільних скорочується на 1–1.5 секунди.

Зображення — головне гальмо. Використовуємо <picture> з WebP та JPEG-фолбеком. loading="lazy" для всього нижче першого екрану. width та height явно прописані — CLS = 0. Обробник в urlrewrite.php генерує WebP на льоту.

Мініфікація та стиснення. CSS та JS через Vite або вбудоване об'єднання Бітрікс. Brotli на nginx (brotli_comp_level 6) — на 15–20% ефективніше за gzip. Кешування статики: expires 1y + версіонування через query string.

Ми готові зробити аудит вашого проєкту та запропонувати конкретні кроки. Закажіть консультацію.

Що входить в послугу верстки сайтів на 1С-Бітрікс?

Після замовлення верстки шаблону або адаптації готового рішення передаємо:

  • Вихідні коди шаблонів компонентів з розділенням на template.php, result_modifier.php, epilog
  • CSS та JS, підключені через Asset — без інлайн-стилів
  • Налаштоване кешування з тегами
  • Документацію за структурою та параметрами
  • Доступ до Git-репозиторію з історією змін
  • Навчання вашого розробника: як правити шаблон без втрати оновлюваності

Гарантуємо відповідність Core Web Vitals та кросбраузерність. Закріплюємо інженера з досвідом 10+ років.

Типові помилки при верстці, які ми виправляємо - Inline-стилі в шаблонах — ламають кешування та об'єднання CSS. - Відсутність `component_epilog.php` — динамічний контент застигає. - Неправильне підключення скриптів через `