Часто стикаємося з ситуацією, коли вбудовані віджети Retool не справляються: потрібно відобразити 10k+ точок на карті з динамічною кластеризацією, а штатний Map-віджет гальмує вже на 500 точках. Або потрібна діаграма з нестандартною анімацією, drag-and-drop сортування з бізнес-правилами, Kanban-дошка з обмеженням WIP. Для таких завдань Retool надає механізм Custom Components — повноцінні React-застосунки, ізольовані в iframe та пов'язані з хостом через postMessage API. Ми побудували понад 50 таких компонентів під ключ для різних бізнес-задач, і накопичили практику, якою ділимося.
Як працюють кастомні компоненти? — розробка кастомних компонентів
Custom Component — це React-застосунок, який спілкується з Retool через бібліотеку @tryretool/custom-component-support. Вона надає React-хуки для синхронізації стану: Retool.useStateValue для читання/запису моделі та Retool.useEventCallback для відправки подій назад до Retool. Середовище розробки — локальний сервер (Vite або CRA), а готова збірка деплоїться на будь-який статичний хостинг.
// src/index.tsx — точка входу кастомного компонента
import { Retool } from '@tryretool/custom-component-support';
interface ModelData {
items: Array<{ id: string; label: string; value: number; color: string }>;
selectedId: string | null;
}
export const BubbleChart: FC = () => {
const [items] = Retool.useStateValue<ModelData['items']>({
name: 'items',
initialValue: [],
label: 'Chart items',
inspector: 'array',
});
const [selectedId, setSelectedId] = Retool.useStateValue<string | null>({
name: 'selectedId',
initialValue: null,
label: 'Selected item ID',
inspector: 'string',
});
const onSelect = Retool.useEventCallback({ name: 'onItemSelect' });
const handleBubbleClick = (id: string) => {
setSelectedId(id);
onSelect({ id });
};
return (
<BubbleChartRenderer
items={items}
selectedId={selectedId}
onSelect={onSelect}
/>
);
}; Чому custom components краще вбудованих віджетів?
Вбудовані віджети покривають 80% типових завдань, але для 20% потрібне кастомне рішення. Порівняйте:
| Критерій | Вбудовані віджети | Кастомні компоненти |
|---|---|---|
| Візуалізація | Стандартні графіки (бар, лінія, пай) | Будь-які: D3.js, Three.js, ECharts |
| Інтерактивність | Базова (фільтри, сортування) | Кастомні події, drag-and-drop, анімації |
| Продуктивність | Обмежена 1–2 тис. рядків | Віртуалізація до 50k+ рядків |
| Гнучкість | Задані властивості | Повний контроль над рендером і логікою |
Для рідкісних форматів (chord diagram, force-directed graph) кастомний компонент — єдиний спосіб.
Типові завдання
Візуалізації: D3.js-графіки (chord diagram, force-directed graph, sankey), ECharts з кастомними серіями, Three.js-попередній перегляд 3D-моделей.
Інтерактивні таблиці: віртуалізовані списки через @tanstack/virtual для 50k+ рядків, inline-редагування з кастомними валідаторами, drag-and-drop сортування через @dnd-kit/core.
Карти: Mapbox GL JS / Leaflet з динамічними кластерами, drawing-інструменти для геозон, ізохрони через Mapbox Isochrone API.
Специфічні UI-патерни: Kanban-дошка з бізнес-обмеженнями, часова шкала Gantt, code editor на базі Monaco.
Що входить в роботу?
Ми розробляємо компонент під ключ: від проектування data contract до деплою та документації. В рамках задачі:
- Узгодження моделі даних і подій.
- Реалізація рендеру та всієї бізнес-логіки.
- Інтеграція з вашим Retool-оточенням (cloud або self-hosted).
- Оптимізація продуктивності (віртуалізація, lazy loading, мемоізація).
- Деплой на CDN або в Retool Toolbox.
- Документація з встановлення та використання.
- Навчання та письмова підтримка протягом 2 тижнів після здачі.
Збірка та деплой
Компонент збирається в єдиний бандл і деплоїться на статику. Retool підтримує два способи підключення: через URL (CDN/S3/Vercel) та через Retool Toolbox для self-hosted інстансів.
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
lib: {
entry: 'src/index.tsx',
name: 'RetoolCustomComponent',
fileName: 'index',
formats: ['umd'],
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
},
},
});
Після vite build — dist/index.umd.js завантажується в CDN або Retool Cloud Storage. В інтерфейсі Retool створюється Custom Component, вказується URL бандла та iframe-URL сторінки.
Передача складних даних
Retool обмежує модель даних серіалізованими типами. Для складних структур (вкладені об'єкти, файли) використовується JSON-серіалізація всередині рядкового поля:
const [rawConfig] = Retool.useStateValue<string>({
name: 'config',
initialValue: '{}',
label: 'JSON Config',
inspector: 'text',
});
const config = useMemo(() => {
try {
return JSON.parse(rawConfig);
} catch {
return {};
}
}, [rawConfig]);Для великих датасетів (тисячі рядків) дані проброшуються через Retool Query, яка повертає JSON — компонент отримує їх напряму без дублювання стану в model.
Як створити кастомний компонент: 5 кроків
- Налаштування проекту: створіть React-застосунок з Vite або CRA, встановіть
@tryretool/custom-component-support. - Визначте data contract: узгодьте з замовником поля моделі (entries, properties) та події (callbacks).
- Реалізуйте рендер та логіку: використовуйте хуки
useStateValueдля читання даних іuseEventCallbackдля відправки подій. - Зберіть бандл: виконайте
vite buildз конфігурацією UMD. - Задеплойте: завантажте бандл на CDN або в Retool Toolbox та вкажіть URL в інтерфейсі Retool.
Приклад конфігурації для CDN
https://cdn.example.com/retool-components/bubble-chart/index.umd.js Після деплою створіть Custom Component в Retool, вставте цей URL — компонент готовий до використання.
Наш досвід і гарантії
Ми давно займаємось low-code платформами та побудували понад 50 кастомних компонентів для Retool. Гарантуємо стабільну роботу та дотримання термінів. Зв'яжіться з нами — оцінимо вашу задачу. Вартість розробки варіюється залежно від складності, але зазвичай окупається за 2–3 місяці використання.







