Dashboard Widget Integration¶
Glint exposes a GET /api/widget endpoint that returns a JSON summary of your Proxmox cluster. Any homepage-style dashboard can consume it without CORS issues — the request is made server-side by the dashboard, not by the browser.
Response Reference¶
{
"nodes": { "total": 3, "online": 3, "offline": 0 },
"guests": { "total": 25, "running": 22, "stopped": 3, "vms": 15, "lxc": 10 },
"cpu": { "usage_pct": 23.4 },
"memory": { "used_bytes": 68719476736, "total_bytes": 274877906944, "usage_pct": 25.0 },
"disks": { "total": 8, "passed": 7, "failed": 0, "warning": 1, "unknown": 0 },
"backups": { "total": 42, "last_backup_time": 1740009600 }
}
| Field | Description |
|---|---|
nodes.total/online/offline |
PVE node counts by status |
guests.total/running/stopped |
Guest counts by status |
guests.vms/lxc |
Guest counts by type |
cpu.usage_pct |
Average CPU % across online nodes |
memory.used_bytes / total_bytes / usage_pct |
Summed memory across online nodes |
disks.passed/failed/warning/unknown |
Disk counts by SMART health category |
backups.total |
Total backup snapshot count across all PBS instances |
backups.last_backup_time |
Most recent backup as a Unix timestamp |
Offline nodes
Offline nodes are counted but excluded from CPU and memory aggregates.
Authentication¶
All dashboard tools listed here make requests server-side, so CORS is not a concern.
If Glint is behind a reverse proxy with authentication, you have two options:
Option A — Exempt /api/widget from auth (same pattern as /healthz):
Option B — Pass credentials in the dashboard widget config (see per-dashboard examples below).
Homepage¶
Homepage uses the built-in customapi widget type. Requests are made by the Next.js server process — no CORS configuration needed.
# services.yaml
- Proxmox:
icon: proxmox.svg
href: http://glint:8080
description: Proxmox VE cluster
widget:
type: customapi
url: http://glint:8080/api/widget
mappings:
- field: nodes.online
label: Nodes
format: number
- field: guests.running
label: Running
format: number
- field: cpu.usage_pct
label: CPU
format: float
suffix: "%"
- field: memory.usage_pct
label: Memory
format: float
suffix: "%"
- field: backups.last_backup_time
label: Last Backup
format: relativeDate
With basic auth on the reverse proxy:
Useful format options:
| Field | Recommended format |
|---|---|
nodes.online |
number |
guests.running |
number |
cpu.usage_pct |
float + suffix: "%" |
memory.usage_pct |
float + suffix: "%" |
memory.used_bytes |
bytes |
backups.last_backup_time |
relativeDate |
backups.total |
number |
Glance¶
Glance uses a custom-api widget with Go template rendering. You have full control over the HTML layout.
# glance.yml
- type: custom-api
title: Proxmox
cache: 1m
url: http://glint:8080/api/widget
template: |
<div class="flex gap-4 justify-around">
<div class="flex flex-col items-center">
<div class="widget-content-block-title">{{ .JSON.Int "nodes.online" }}/{{ .JSON.Int "nodes.total" }}</div>
<div class="color-subdue text-sm">Nodes</div>
</div>
<div class="flex flex-col items-center">
<div class="widget-content-block-title">{{ .JSON.Int "guests.running" }}</div>
<div class="color-subdue text-sm">Running</div>
</div>
<div class="flex flex-col items-center">
<div class="widget-content-block-title">{{ .JSON.Float "cpu.usage_pct" | printf "%.1f" }}%</div>
<div class="color-subdue text-sm">CPU</div>
</div>
<div class="flex flex-col items-center">
<div class="widget-content-block-title">{{ .JSON.Float "memory.usage_pct" | printf "%.1f" }}%</div>
<div class="color-subdue text-sm">Memory</div>
</div>
</div>
{{ if gt (.JSON.Int "disks.failed") 0 }}
<p class="color-negative text-sm margin-top-10">
⚠ {{ .JSON.Int "disks.failed" }} disk(s) failed SMART
</p>
{{ end }}
With basic auth on the reverse proxy:
Accessing fields:
| Type | Accessor |
|---|---|
| Integer | {{ .JSON.Int "nodes.online" }} |
| Float | {{ .JSON.Float "cpu.usage_pct" }} |
| Unix timestamp | {{ toRelativeTime (parseTime "Unix" (printf "%d" (.JSON.Int "backups.last_backup_time"))) }} |
Dashy¶
Dashy uses the api-response widget type with a fields mapping.
# conf.yml
sections:
- name: Infrastructure
items:
- title: Proxmox Cluster
icon: si-proxmox
type: api-response
options:
url: http://glint:8080/api/widget
updateInterval: 60
fields:
- label: Nodes Online
key: nodes.online
- label: Guests Running
key: guests.running
- label: CPU Usage
key: cpu.usage_pct
- label: Memory Usage
key: memory.usage_pct
- label: Disks Failed
key: disks.failed
- label: Last Backup
key: backups.last_backup_time
With basic auth on the reverse proxy:
Dashy useProxy option
If you access Glint from a browser-side Dashy deployment and hit CORS errors,
set useProxy: true. This routes the request through Dashy's server-side proxy.
For Docker-network deployments where Dashy's Node.js server calls Glint directly,
it is not needed.
All dashboards at a glance¶
| Dashboard | Widget type | Auth support | Request origin |
|---|---|---|---|
| Homepage | customapi |
username / password fields |
Server-side (Next.js) |
| Glance | custom-api |
headers field |
Server-side (Go) |
| Dashy | api-response |
headers field or useProxy |
Server-side (Node.js) |