Hi. Since you are just starting out, I'd probably recommend not using node-red-dashboard (aka dashboard 1) as it is depreciated. Instead, @flowfuse/node-red-dashboard (aka dashboard-2) which is in active development.
I recently start using uibuilder, there it is possible. My approach:
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="../uibuilder/images/node-blue.ico">
<title>Minimal modern ESM client example - Node-RED uibuilder</title>
<meta name="description" content="Node-RED uibuilder - Minimal modern ESM client example">
<!-- Your own CSS -->
<link type="text/css" rel="stylesheet" href="./index.css" media="all">
<!-- NOTE this MUST be loaded as a MODULE. Also, uib client loaded in index not here -->
<script type="module" async src="./index.js">
/* Your custom code + Imports uibuilder */
</script>
<style>
svg {
width: 100%;
max-width: 600px;
display: block;
margin: auto;
}
text {
font-size: 14px;
font-weight: bold;
text-anchor: middle;
}
</style>
</head>
<body class="">
<svg viewBox="0 0 400 400">
<!-- Komponenten -->
<rect id="pv" x="150" y="20" width="100" height="50" fill="gold" stroke="black" />
<text x="200" y="45">PV-Power</text>
<text id="pv_power" x="200" y="60">0 kW</text>
</svg>
</body>
</html>
and in index.js i have this little function:
function updateFlows(pvPower) {
document.getElementById('pv_power').textContent = pvPower.toFixed(2) + ' kW';
}
// Listen for incoming messages from Node-RED and action
uibuilder.onChange('msg', (msg) => {
// do stuff with the incoming msg
if (msg.topic == "updateFlow") {
updateFlows(msg.payload)
}
})