Разработка кастомных компонентов Retool
Retool покрывает большинство задач внутренних инструментов встроенными виджетами. Но рано или поздно появляется требование, под которое готового компонента нет: специфическая визуализация данных, интерактивная карта с кастомными маркерами, сложный drag-and-drop с бизнес-логикой. Для этого Retool предоставляет механизм Custom Components — iframe-изолированные React-приложения, встроенные в интерфейс через postMessage API.
Как работает механизм Custom Components
Кастомный компонент в Retool — это полноценное React-приложение, которое живёт в изолированном iframe. Взаимодействие с хостом строится через Retool.useStateValue и Retool.useEventCallback. Данные передаются из Retool в компонент через model, компонент отправляет события обратно через triggerQuery или произвольные event-коллбеки.
Окружение разработки — локальный сервер (Vite или CRA), код деплоится на любой статичный хостинг или загружается напрямую в Retool.
Структура компонента
// 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={handleBubbleClick}
/>
);
};
Пакет @tryretool/custom-component-support — обязательная зависимость. Он абстрагирует postMessage и предоставляет React-хуки для синхронизации состояния.
Сборка и деплой
Компонент собирается в единый бандл и деплоится на статику. 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.
Типичные задачи, под которые пишутся кастомные компоненты
Визуализации: 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.
Что происходит при разработке
День 1–2: настройка проекта (Vite + React + TypeScript + Retool SDK), договорённость по data contract — какие поля в модели, какие события наружу. Минимальный рабочий компонент с mock-данными.
День 3–4: реализация логики и рендера. Параллельно — тестирование интеграции с реальным Retool-окружением клиента (cloud или self-hosted — имеет значение, версии SDK различаются).
День 5: обработка крайних случаев, загрузка данных, стилизация под дизайн-систему клиента, деплой на CDN, передача компонента с документацией.
Компонент средней сложности (кастомный график или интерактивная карта без сложной логики) — 3–5 дней. Kanban или Gantt с drag-and-drop и персистентностью — 1–2 недели.







