diff --git a/docs/widgets/services/frigate.md b/docs/widgets/services/frigate.md
new file mode 100644
index 000000000..53421ab43
--- /dev/null
+++ b/docs/widgets/services/frigate.md
@@ -0,0 +1,14 @@
+---
+ title: Frigate
+ description: Frigate Widget Configuration
+ ---
+
+ Learn more about [Frigate](https://frigate.video/).
+
+ Allowed fields: `["cameras", "uptime", "version"]`.
+
+ ```yaml
+ widget:
+ type: frigate
+ url: http://frigate.host.or.ip:port
+ ```
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 26f5fe0a2..8c07b386f 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -55,6 +55,7 @@ nav:
- widgets/services/fileflows.md
- widgets/services/flood.md
- widgets/services/freshrss.md
+ - widgets/services/frigate.md
- widgets/services/fritzbox.md
- widgets/services/gamedig.md
- widgets/services/gatus.md
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index c0314d4e5..b21c9a357 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -900,5 +900,11 @@
"open": "Open - US Market",
"closed": "Closed - US Market",
"invalidConfiguration": "Invalid Configuration"
+ },
+ "frigate": {
+ "camera": "Camera",
+ "cameras": "Cameras",
+ "uptime": "Uptime",
+ "version": "Version"
}
}
diff --git a/src/widgets/components.js b/src/widgets/components.js
index 215de0421..341f5211d 100644
--- a/src/widgets/components.js
+++ b/src/widgets/components.js
@@ -29,6 +29,7 @@ const components = {
fileflows: dynamic(() => import("./fileflows/component")),
flood: dynamic(() => import("./flood/component")),
freshrss: dynamic(() => import("./freshrss/component")),
+ frigate: dynamic(() => import("./frigate/component")),
fritzbox: dynamic(() => import("./fritzbox/component")),
gamedig: dynamic(() => import("./gamedig/component")),
gatus: dynamic(() => import("./gatus/component")),
diff --git a/src/widgets/frigate/component.jsx b/src/widgets/frigate/component.jsx
new file mode 100644
index 000000000..f74b95a8e
--- /dev/null
+++ b/src/widgets/frigate/component.jsx
@@ -0,0 +1,47 @@
+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, error } = useWidgetAPI(widget, "stats");
+
+ if (error) {
+ return ;
+ }
+
+ if (!data) {
+ return (
+
+
+
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
+ );
+}
diff --git a/src/widgets/frigate/widget.js b/src/widgets/frigate/widget.js
new file mode 100644
index 000000000..4edcc5f77
--- /dev/null
+++ b/src/widgets/frigate/widget.js
@@ -0,0 +1,24 @@
+import { asJson } from "utils/proxy/api-helpers";
+import genericProxyHandler from "utils/proxy/handlers/generic";
+
+// export default widget;
+const widget = {
+ api: "{url}/api/{endpoint}",
+ proxyHandler: genericProxyHandler,
+
+ mappings: {
+ "stats": {
+ endpoint: "stats",
+ map: (data) => {
+ const jsonData = asJson(data);
+ return {
+ num_cameras: jsonData?.cameras !== undefined ? Object.keys(jsonData?.cameras).length : 0,
+ uptime: jsonData?.service?.uptime,
+ version: jsonData?.service.version,
+ }
+ },
+ },
+ },
+};
+
+export default widget;
diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js
index c053e6c1b..a72a4126d 100644
--- a/src/widgets/widgets.js
+++ b/src/widgets/widgets.js
@@ -23,6 +23,7 @@ import evcc from "./evcc/widget";
import fileflows from "./fileflows/widget";
import flood from "./flood/widget";
import freshrss from "./freshrss/widget";
+import frigate from "./frigate/widget";
import fritzbox from "./fritzbox/widget";
import gamedig from "./gamedig/widget";
import gatus from "./gatus/widget";
@@ -141,6 +142,7 @@ const widgets = {
fileflows,
flood,
freshrss,
+ frigate,
fritzbox,
gamedig,
gatus,