* feat(custom-widgets): improve authoring workbench * fix(custom-widgets): address review and CI * refactor(custom-widgets): satisfy architecture checks * fix(custom-widgets): isolate workbench typing updates * fix(custom-widgets): harden workbench state
75 lines
4.6 KiB
Plaintext
75 lines
4.6 KiB
Plaintext
# Create a Custom Widget
|
|
|
|
import { CanonicalCustomWidgetExample } from "@site/src/components/custom-widget-code";
|
|
import workbenchImage from "./img/workbench.png";
|
|
import workbenchMobileImage from "./img/workbench-mobile.png";
|
|
import workbenchValidationImage from "./img/workbench-validation.png";
|
|
|
|
The workbench exposes **General**, **API sources**, **Requests**, **Options**, **JSX**, and **Preview** sections. Advanced JSON is
|
|
available in the manifest and request/option editors. Code and preview sit side by side on desktop; on smaller screens the
|
|
**Configure**/**Preview** switch shows one pane at a time and the section navigation scrolls horizontally. Preview sizes display
|
|
as **S/M/L** (Compact/Standard/Wide), and fixtures are **Live**, **Loading**, **Empty**, or **Error**.
|
|
For multiline JSX, prefer `templateLines` in agent or MCP input and keep the final tested preview as the source of truth before saving.
|
|
|
|
<img
|
|
src={workbenchImage}
|
|
alt="Custom Widget workbench with configuration sections and a live preview"
|
|
style={{ maxWidth: "100%" }}
|
|
/>
|
|
|
|
<img
|
|
src={workbenchMobileImage}
|
|
alt="Mobile Custom Widget workbench with Configure and Preview switch and horizontally scrollable section navigation"
|
|
style={{ maxWidth: "100%" }}
|
|
/>
|
|
|
|
The workbench keeps the configuration and preview together so you can inspect validation diagnostics, the redacted request
|
|
journal, fixture data, and preview size before saving. Invalid fields stay marked in the form while the preview explains why it
|
|
needs attention.
|
|
|
|
<img
|
|
src={workbenchValidationImage}
|
|
alt="Custom Widget workbench showing a Base URL validation error with Test, preview, and Create actions disabled"
|
|
style={{ maxWidth: "100%" }}
|
|
/>
|
|
|
|
## Manual workflow
|
|
|
|
1. Configure the default API source, network scope, authentication, and credential.
|
|
2. Add query/action cards. Values can be literals, widget options, or invocation parameters.
|
|
3. Add widget options with their control and default value.
|
|
4. Write responsive JSX using `data`, `status`, `options`, and temporary `inputs`.
|
|
5. Test and preview, inspect Data and the redacted request journal, then save.
|
|
|
|
While focus is inside a code editor, use `Ctrl+Z`/`Cmd+Z` to undo and `Ctrl+Shift+Z`/`Cmd+Shift+Z` to redo. The toolbar exposes the same actions. This history is local to that editor; builder-wide undo is not yet available.
|
|
|
|
Changing the definition, instance options, or credentials invalidates the previous preview and its live-action session. Run **Test and preview** again before treating the data or result as current. Automatic load queries are queued with up to four running at once so larger previews stay within the request limit.
|
|
|
|
<CanonicalCustomWidgetExample
|
|
id="named-widget-requests"
|
|
label="Named queries and actions"
|
|
example="requests"
|
|
height="420px"
|
|
/>
|
|
|
|
<CanonicalCustomWidgetExample id="widget-options" label="Widget options" example="options" height="360px" />
|
|
|
|
Every option has a default. Supported controls include text, textarea, number, switch, select, multi-select, slider, date, time, color, icon, URL, duration, time zone, and JSON. Dynamic choices use `choicesFrom: { request, itemsPath?, valuePath, labelPath }`; the request must be a load query without invocation parameters, and you cannot provide both static `choices` and `choicesFrom`.
|
|
|
|
Preview actions are simulated by default and recorded in the journal without contacting the service. Enable **Run actions against the configured API** only when you intend a real mutation; live actions still require configured confirmation.
|
|
|
|
## ChatGPT or Claude
|
|
|
|
Open **Create or fix with any AI**, enter the desired widget and optional API documentation URL, then select the copy action beside the accordion title. The single self-contained prompt is below 12,000 characters, starts with your request, includes the lean contract and two polished examples, and never claims that an offline chat has MCP tools.
|
|
|
|
The model must return one fenced `json` block containing the complete widget, including the JSX in its `template`
|
|
field. Copy that single block and select **Paste**. Homarr fills the visual builders and the JSX editor
|
|
without any placeholder replacement or second paste.
|
|
|
|
Homarr shows all actionable schema or JSX errors inline. Enter credentials separately. The copied prompt does not include the
|
|
latest preview response; use **Preview** > **Data** to inspect it and mention important response fields in your request. The prompt deliberately
|
|
recommends a focused Mantine component set, visual hierarchy, responsive layout, theme compatibility, and loading,
|
|
empty, failure, and success states.
|
|
|
|
Connected agents should use the skills.sh skill and retrieve the live schema and individual component metadata only as needed.
|