Розробка кастомних віджетів Appsmith

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка кастомних віджетів Appsmith
Середня
~3-5 робочих днів
Часті питання

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

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

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

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розроблення користувацьких віджетів у Appsmith

Appsmith — це відкритий вихідний код конкурент Retool з подібною моделлю кастомізації. Custom Widget у Appsmith — це також iframe з postMessage, але API дещо відрізняється. Тоді як Retool використовує npm-пакет з гаками, Appsmith надає глобальний об'єкт appsmith прямо в контексту iframe.

Механізм Custom Widget

Користувацький віджет у Appsmith отримує дані через appsmith.model, надсилає события через appsmith.triggerEvent і оновлює стан через appsmith.updateModel. Все це синхронізується з основною програмою через postMessage без необхідності встановлювати SDK.

Віджет підключається як HTML-сторінка — можна писати ванільний JS прямо в редакторі Appsmith або задати зовнішній URL із зібраним бандлом.

Вбудований редактор проти зовнішнього бандлу

Для простих компонентів — код прямо у Appsmith:

<!-- Вбудований HTML у редакторі Custom Widget -->
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
</head>
<body>
  <canvas id="chart"></canvas>
  <script>
    let chart = null;

    function initChart(data) {
      const ctx = document.getElementById('chart').getContext('2d');
      chart = new Chart(ctx, {
        type: 'doughnut',
        data: {
          labels: data.map(d => d.label),
          datasets: [{
            data: data.map(d => d.value),
            backgroundColor: data.map(d => d.color),
          }],
        },
        options: {
          responsive: true,
          onClick: (event, elements) => {
            if (elements.length > 0) {
              const idx = elements[0].index;
              appsmith.triggerEvent('onSegmentClick', { item: data[idx] });
            }
          },
        },
      });
    }

    // Ініціалізація при завантаженні
    appsmith.onReady(() => {
      initChart(appsmith.model.items || []);
    });

    // Реакція на зміну даних
    appsmith.onModelChange((model) => {
      if (chart) {
        chart.data.labels = model.items.map(d => d.label);
        chart.data.datasets[0].data = model.items.map(d => d.value);
        chart.update();
      }
    });
  </script>
</body>
</html>

Для складних компонентів з React та TypeScript — зовнішній бандл:

// src/Widget.tsx
import { useEffect, useState } from 'react';

declare global {
  interface Window {
    appsmith: {
      model: Record<string, unknown>;
      onReady: (cb: () => void) => void;
      onModelChange: (cb: (model: Record<string, unknown>) => void) => void;
      triggerEvent: (name: string, payload?: unknown) => void;
      updateModel: (updates: Record<string, unknown>) => void;
    };
  }
}

interface ScheduleItem {
  id: string;
  title: string;
  start: string;
  end: string;
  resourceId: string;
}

export function SchedulerWidget() {
  const [items, setItems] = useState<ScheduleItem[]>([]);
  const [resources, setResources] = useState([]);

  useEffect(() => {
    window.appsmith.onReady(() => {
      const model = window.appsmith.model;
      setItems((model.items as ScheduleItem[]) || []);
      setResources((model.resources as []) || []);
    });

    window.appsmith.onModelChange((model) => {
      setItems((model.items as ScheduleItem[]) || []);
      setResources((model.resources as []) || []);
    });
  }, []);

  const handleEventDrop = (item: ScheduleItem, newStart: string, newEnd: string) => {
    const updated = { ...item, start: newStart, end: newEnd };
    window.appsmith.triggerEvent('onEventReschedule', { item: updated });
    window.appsmith.updateModel({ lastAction: { type: 'reschedule', item: updated } });
  };

  return (
    <FullCalendarWrapper
      items={items}
      resources={resources}
      onEventDrop={handleEventDrop}
    />
  );
}

Побудова для зовнішнього розгортання

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    outDir: 'dist',
    rollupOptions: {
      input: 'index.html',
    },
  },
  base: './',
});

index.html у dist розгортається на Vercel/Netlify/S3 із публічним доступом. У Custom Widget Appsmith вказуєте URL на index.html.

Передача подій та двостороння синхронізація

// Оновлення стану віджета з коду Appsmith (через Model binding)
// У полі "Default Model" у налаштуваннях віджета:
{
  "items": "{{fetchData.data}}",
  "selectedId": "{{appState.selectedItem}}"
}

// У віджеті — реакція на зміну selectedId
appsmith.onModelChange((model) => {
  highlightItem(model.selectedId);
});

// З віджета — оновити глобальний стан Appsmith
appsmith.updateModel({ selectedId: clickedItem.id });

// Це значення доступне як Widget.model.selectedId у інших запитах та віджетах

Різниці з Retool в розробці

У Retool можна використовувати npm-пакети через bundler безперебійно. У Appsmith вбудований редактор не має npm — тільки CDN. Для серйозних компонентів завжди потрібен зовнішній бандл. Однак Appsmith повністю з відкритим вихідним кодом — може бути самостійно розгорнутим без обмежень ліцензії, і користувацькі віджети будуть працювати однаково у хмарі та при самостійному розгортанні.

Типові задачі

Найчастіші запити: Gantt-планувальник ресурсів (FullCalendar + користувацький вигляд ресурсів), карти теплових виділень активності (D3 або ECharts heatmap), вбудований редактор складних конфігів JSON (Monaco Editor), геоаналітика (Mapbox GL з фільтрами з Appsmith).

Часові шкали

Простий компонент на Chart.js або аналогічній з передачею даних та однією подією — 1–2 дні. Компонент з двостороннією синхронізацією стану, користувацьким стилем та складною інтерактивністю — 3–5 днів. Важкий планувальник або сітка даних з персистентністю — 1–2 тижні.