diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 62ef2102..308f1e63 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -298,5 +298,9 @@
"rejectedPushes": "Rejected",
"filters": "Filters",
"indexers": "Indexers"
+ },
+ "scripted": {
+ "yes": "Yes",
+ "no": "No"
}
}
diff --git a/src/widgets/components.js b/src/widgets/components.js
index f46808a5..27d3c14e 100644
--- a/src/widgets/components.js
+++ b/src/widgets/components.js
@@ -30,6 +30,7 @@ const components = {
readarr: dynamic(() => import("./readarr/component")),
rutorrent: dynamic(() => import("./rutorrent/component")),
sabnzbd: dynamic(() => import("./sabnzbd/component")),
+ scripted: dynamic(() => import("./scripted/component")),
sonarr: dynamic(() => import("./sonarr/component")),
speedtest: dynamic(() => import("./speedtest/component")),
strelaysrv: dynamic(() => import("./strelaysrv/component")),
diff --git a/src/widgets/scripted/README.md b/src/widgets/scripted/README.md
new file mode 100644
index 00000000..cf16f770
--- /dev/null
+++ b/src/widgets/scripted/README.md
@@ -0,0 +1,50 @@
+# Widget for displaying scripted information
+
+This widget executes a script and displays the script's output. The executed script must return
+the data in json format. The returned fields can be filtered, labeled and formatted.
+
+For example to display the online status and number of players of a minecraft server the
+configuration could be:
+
+```yaml
+ widget:
+ type: scripted
+ script: "mcstatus myserver:25565 json"
+ fields: [ "online", "player_count", "ping" ]
+ field_labels:
+ player_count: "players"
+ field_types:
+ online: boolean
+ ping:
+ type: common.ms
+ style: unit
+ unit: millisecond
+ unitDisplay: narrow
+```
+
+The output of the executed script of the above example is
+
+```json
+{ "online": true, "version": "1.19.2", "protocol": 760, "motd": "A Minecraft server", "player_count": 0, "player_max": 20, "players": [], "ping": 0.527 }
+```
+
+From the scripts output the three fields online, player_count and ping
+will be displayed. The field player_count will be named "players". The fields online
+and ping will be formatted.
+
+## Configuration
+
+* **script** is the script that will be executed as the user that runs the homepage server.
+ It's output must be in JSON format.
+
+* **fields** names the fields from the script's output that shall be displayed.
+ It is recommended to set the fields. Otherwise the widget will be empty if no data can be displayed.
+
+* **field_labels** defines the labels to be displayed for the fields. The field name itself is used if there
+ is no label for a field, like for the fields online and ping in the example.
+
+* **field_types** defines the types of the fields. If unset then the value is shown unformatted.
+ The type's value can either be a simple string like common.number or a map if multiple
+ configuration options shall be used like in the example above for the ping field.
+ See the "common.XY" translation strings in the file public/locales/en/common.json for
+ supported field types. In addition the type boolean is supported.
diff --git a/src/widgets/scripted/component.jsx b/src/widgets/scripted/component.jsx
new file mode 100644
index 00000000..095fd180
--- /dev/null
+++ b/src/widgets/scripted/component.jsx
@@ -0,0 +1,49 @@
+import { useTranslation } from "next-i18next";
+
+import Container from "components/services/widget/container";
+import Block from "components/services/widget/block";
+import useWidgetAPI from "utils/proxy/use-widget-api";
+
+export default function Component({ service }) {
+ const { t } = useTranslation();
+
+ const { widget } = service;
+
+ const { data: scriptedData, error: scriptedError } = useWidgetAPI(widget, '');
+
+ if (scriptedError) {
+ return