Homarr
ManagementCustom Widgets

Custom Widgets

A Custom Widget is a validated homarr-custom-widget-v2 definition containing API sources, queries and actions, optional settings, and a safe JSX template.

Homarr executes requests on the server and renders the template in a restricted runtime. Source credentials are encrypted separately and are not included in exports, prompts, browser data, or Workshop submissions.

Source credentials are stored separately and excluded from exports, prompts, and Workshop submissions.

The Custom Widgets management page

Manage Custom Widgets

Administrators can create, import, duplicate, enable, export, publish, and delete definitions under Management → Custom Widgets. Adding or configuring one on a board also requires permission to modify that board. Use Actions → Configure sources to update deployment-specific URLs, network access, and encrypted credentials without reopening the authoring workbench.

Once placed, normal board permissions control rendering and requests. Queries can run for anonymous viewers on public boards; actions require authentication and the permission declared by the request.

Authoring

The workbench validates the same schema used by imports, Workshop, HTTP authoring resources, and MCP. Test every query and simulate relevant actions before saving. Live preview actions are opt-in because they can change the source service.

Import and Workshop

Use Import from Workshop while adding board content or import a v2 JSON definition directly. Review the source, requested permissions, API hosts, and actions before installation, then configure deployment-specific URLs and credentials in Homarr.

Legacy definitions show Migration required. The migration prompt excludes credentials and the old display template; describe the visible behavior separately, import the returned v2 definition, and verify it before removing the archived version.

Keep SECRET_ENCRYPTION_KEY unchanged when updating Homarr so existing credentials remain readable. Multi-replica installations must use the same Redis service so cached responses invalidate consistently.

On this page