How to add images to Node-RED dashboards when using FlowFuse
Import your images into your Node-RED dashboards, wherever you are running your instances

Using images in your Node-RED dashboards can significantly improve your users' experience. The most common method to add images to dashboards, is to store them within the filesystem of an Node-RED instance but sometimes that's not an option. How can you easily use images when working in a containerised environment such as Docker, Kubernetes, or FlowFuse?
When designing a dashboard, images allow you to significantly enrich your content. Some examples include:
-
displaying maps to guide engineers to a problem which needs resolving.
-
displaying pictures of specific hardware on a factory-floor which needs to be checked.
-
displaying physical tools which should be used to resolve a problem.
# Why not just store them in Node-RED's host operating system?
Storing images locally can work well when you can access and edit the images on an operating system, but that approach doesn't scale if you are moving instances through a DevOps pipeline. It can also not work well when deploying to environments where you don't have easy access to the host operating system.
How can we include images in dashboards, and be confident that a given build of an application will show the correct images, no matter where your Node-RED instances are hosted?
# Inspiration
There are various solutions to this problem, I wanted to share one I came across when working with a FlowFuse customer recently. I've modified the flows to make them more general in design, but the underlying principal is the same. I asked if I was OK to credit the customer but they said there was no need. Thanks for the inspiration, kind customer!
# Solution explanation
There are three key sections to this solution:
-
Pull the images we need from URLs
-
Store those images in the temporary filesystem of Node-RED
-
Serve up those images as needed in the dashboard
It is possible for us to skip step 2, but I wanted to have the images stored locally, in the Node-RED instance. storing the images locally will improve the loading times of the dashboard. This is especially beneficial when your dashboard is dynamically displaying relevant images, e.g. to show an image of a specific machine which needs to be attended to.
The key benefit of pulling the images from URLs this way is, no matter where you are running Node-RED, the correct images will be shown in your dashboard.
# File and file-in nodes
I've included the flows as json below so you can try them out yourself. Please note, I'm using FlowFuse's own file and file-in nodes in these examples. If you want to use these flows on hosting other than FlowFuse, you will need to replace the nodes with the standard Node-RED file and file-in nodes.
# Custom nodes used
These flows use a few very useful custom nodes which you will need to add manually via the palette manager, they are:
- node-red-contrib-calc - "A Node-Red node to perform basic mathematical calculations".
- node-red-contrib-image-output - "Easy way of previewing and examining images in your flows".
- node-red-contrib-os - "Node-Red nodes for obtaining cpu system information".
- node-red-contrib-string - "Provides a string manipulation node with a chainable UI based on the concise and lightweight stringjs.com".
- node-red-dashboard - "A set of dashboard nodes for Node-RED".
- node-red-node-base64 - "A Node-RED node to pack and unpack objects to base64 format".
# The flows
The first flow takes image URLs in an array, each image is downloaded, processed, then saved to the local file storage. Let's take a look at the flow:
You can import this flow into Node-RED using the code below:
[{"id":"6b8059f703d0f574","type":"group","z":"c6f2a894be05d857","name":"Write the images to disk from the URLs","style":{"label":true},"nodes":["04fb6911559797a0","8a3c077f0f85a905","22c5026dd58e418b","6fcca5cfee2bcb89"],"x":38,"y":53,"w":1004,"h":434},{"id":"04fb6911559797a0","type":"group","z":"c6f2a894be05d857","g":"6b8059f703d0f574","name":"Inject the image URLs to download","style":{"label":true},"nodes":["e635ceb0577a86d5","29fe40a054be5b2b","1e81a35c27aae6ad"],"x":74,"y":79,"w":502,"h":82},{"id":"e635ceb0577a86d5","type":"inject","z":"c6f2a894be05d857","g":"04fb6911559797a0","name":"Send in image URLs as an array","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[\"https://openjsf.org/wp-content/uploads/sites/84/2023/02/ff-logo-wordmark-light_4x.png\",\"https://nodered.org/images/nr-image-1.png\",\"/img/screen-pseudo-overview-2QvTVle3Mr-384.avif\"]","payloadType":"json","x":250,"y":120,"wires":[["29fe40a054be5b2b"]]},{"id":"29fe40a054be5b2b","type":"split","z":"c6f2a894be05d857","g":"04fb6911559797a0","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":450,"y":120,"wires":[["1e81a35c27aae6ad"]]},{"id":"1e81a35c27aae6ad","type":"link out","z":"c6f2a894be05d857","g":"04fb6911559797a0","name":"link out 3","mode":"link","links":["f582702ec222069c"],"x":535,"y":120,"wires":[]},{"id":"8a3c077f0f85a905","type":"group","z":"c6f2a894be05d857","g":"6b8059f703d0f574","name":"Download the images","style":{"label":true},"nodes":["453f3b9d7d312bd2","ecbd7b1a410ecd9d","4d650baa2118036e","f582702ec222069c"],"x":84,"y":179,"w":532,"h":82},{"id":"453f3b9d7d312bd2","type":"http request","z":"c6f2a894be05d857","g":"8a3c077f0f85a905","name":"Get the image","method":"GET","ret":"bin","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":460,"y":220,"wires":[["4d650baa2118036e"]]},{"id":"ecbd7b1a410ecd9d","type":"change","z":"c6f2a894be05d857","g":"8a3c077f0f85a905","name":"Set URL to download","rules":[{"t":"move","p":"payload","pt":"msg","to":"url","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":260,"y":220,"wires":[["453f3b9d7d312bd2"]]},{"id":"4d650baa2118036e","type":"link out","z":"c6f2a894be05d857","g":"8a3c077f0f85a905","name":"link out 1","mode":"link","links":["8bc38803dec97185"],"x":575,"y":220,"wires":[]},{"id":"f582702ec222069c","type":"link in","z":"c6f2a894be05d857","g":"8a3c077f0f85a905","name":"link in 3","links":["1e81a35c27aae6ad"],"x":125,"y":220,"wires":[["ecbd7b1a410ecd9d"]]},{"id":"22c5026dd58e418b","type":"group","z":"c6f2a894be05d857","g":"6b8059f703d0f574","name":"Save the images to the local storage","style":{"label":true},"nodes":["95c819560d22f394","0fe7f013b6356c5d","7edc6cb2b0d243db","829bfc8e6e293ada","8bc38803dec97185","98980d88013c6e12"],"x":84,"y":279,"w":932,"h":82},{"id":"95c819560d22f394","type":"base64","z":"c6f2a894be05d857","g":"22c5026dd58e418b","name":"convert to base64","action":"str","property":"payload","x":250,"y":320,"wires":[["829bfc8e6e293ada"]]},{"id":"0fe7f013b6356c5d","type":"file","z":"c6f2a894be05d857","g":"22c5026dd58e418b","name":"Write file to storage","filename":"filename","filenameType":"msg","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":850,"y":320,"wires":[["98980d88013c6e12"]]},{"id":"7edc6cb2b0d243db","type":"string","z":"c6f2a894be05d857","g":"22c5026dd58e418b","name":"Get filename from the URL","methods":[{"name":"getRightMost","params":[{"type":"str","value":"/"}]}],"prop":"responseUrl","propout":"filename","object":"msg","objectout":"msg","x":620,"y":320,"wires":[["0fe7f013b6356c5d"]]},{"id":"829bfc8e6e293ada","type":"image","z":"c6f2a894be05d857","g":"22c5026dd58e418b","name":"preview","width":"150","data":"payload","dataType":"msg","thumbnail":false,"active":true,"pass":true,"outputs":1,"x":420,"y":320,"wires":[["7edc6cb2b0d243db"]]},{"id":"8bc38803dec97185","type":"link in","z":"c6f2a894be05d857","g":"22c5026dd58e418b","name":"link in 1","links":["4d650baa2118036e"],"x":125,"y":320,"wires":[["95c819560d22f394"]]},{"id":"98980d88013c6e12","type":"link out","z":"c6f2a894be05d857","g":"22c5026dd58e418b","name":"link out 2","mode":"link","links":["1e94b5bab542830a"],"x":975,"y":320,"wires":[]},{"id":"6fcca5cfee2bcb89","type":"group","z":"c6f2a894be05d857","g":"6b8059f703d0f574","name":"Output a debug once all images have been processed","style":{"label":true},"nodes":["d1a6feea3ac829c6","119f8008752bc4fb","1e94b5bab542830a"],"x":64,"y":379,"w":382,"h":82},{"id":"d1a6feea3ac829c6","type":"debug","z":"c6f2a894be05d857","g":"6fcca5cfee2bcb89","name":"debug 140","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":330,"y":420,"wires":[]},{"id":"119f8008752bc4fb","type":"join","z":"c6f2a894be05d857","g":"6fcca5cfee2bcb89","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":190,"y":420,"wires":[["d1a6feea3ac829c6"]]},{"id":"1e94b5bab542830a","type":"link in","z":"c6f2a894be05d857","g":"6fcca5cfee2bcb89","name":"link in 2","links":["98980d88013c6e12"],"x":105,"y":420,"wires":[["119f8008752bc4fb"]]}]
We've now downloaded the images we need, and saved them to our local storage, to make them load more quickly when a user views them in the dashboard.
Onto the second flow, which will get the images from the local storage and then load them into the dashboard. Let's take a look at it:
You can import this flow into Node-RED using the code below:
[{"id":"c0f2a076e4449f10","type":"group","z":"c6f2a894be05d857","name":"Get the images from the filestore and display in the Dashboard","style":{"label":true},"nodes":["a671e373b7ca0be8","767590694c5a17f7","fb1ce2ca6b73d950","fee0b4a8fff9f4aa","c9930135726cf256","806b98a5bdf7ceea","b58daed1ee453873"],"x":48,"y":513,"w":954,"h":654},{"id":"a671e373b7ca0be8","type":"junction","z":"c6f2a894be05d857","g":"c0f2a076e4449f10","x":320,"y":560,"wires":[[]]},{"id":"767590694c5a17f7","type":"junction","z":"c6f2a894be05d857","g":"c0f2a076e4449f10","x":320,"y":640,"wires":[[]]},{"id":"fb1ce2ca6b73d950","type":"group","z":"c6f2a894be05d857","g":"c0f2a076e4449f10","name":"Get the images from the local storage","style":{"label":true},"nodes":["924666bcda6c633b","e6f985ed4ff557b5","bee4039410549ec8","83477da8696ae6e7"],"x":84,"y":679,"w":492,"h":82},{"id":"924666bcda6c633b","type":"image","z":"c6f2a894be05d857","g":"fb1ce2ca6b73d950","name":"preview","width":"150","data":"payload","dataType":"msg","thumbnail":false,"active":true,"pass":true,"outputs":1,"x":440,"y":720,"wires":[["83477da8696ae6e7"]]},{"id":"e6f985ed4ff557b5","type":"file in","z":"c6f2a894be05d857","g":"fb1ce2ca6b73d950","name":"Read file from storage","filename":"payload","filenameType":"msg","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":260,"y":720,"wires":[["924666bcda6c633b"]]},{"id":"bee4039410549ec8","type":"link in","z":"c6f2a894be05d857","g":"fb1ce2ca6b73d950","name":"link in 4","links":["b669ea3caf594f9a"],"x":125,"y":720,"wires":[["e6f985ed4ff557b5"]]},{"id":"83477da8696ae6e7","type":"link out","z":"c6f2a894be05d857","g":"fb1ce2ca6b73d950","name":"link out 5","mode":"link","links":["044af6d97af553e4"],"x":535,"y":720,"wires":[]},{"id":"fee0b4a8fff9f4aa","type":"group","z":"c6f2a894be05d857","g":"c0f2a076e4449f10","name":"Prepare each image to be shown in the dashboard","style":{"label":true},"nodes":["8cb8c95c2f5a1591","6eabd7a88e3863d3","044af6d97af553e4","264eb6e2f10c1ab5"],"x":84,"y":779,"w":832,"h":82},{"id":"8cb8c95c2f5a1591","type":"change","z":"c6f2a894be05d857","g":"fee0b4a8fff9f4aa","name":"Add the file type to the mimetype, add to image content","rules":[{"t":"set","p":"mimetype","pt":"msg","to":"\"data:image/\"&msg.filetype&\";base64,\"","tot":"jsonata"},{"t":"set","p":"output","pt":"msg","to":"msg.mimetype&msg.payload","tot":"jsonata"},{"t":"move","p":"output","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":820,"wires":[["264eb6e2f10c1ab5"]]},{"id":"6eabd7a88e3863d3","type":"string","z":"c6f2a894be05d857","g":"fee0b4a8fff9f4aa","name":"Get file type from file name","methods":[{"name":"getRightMost","params":[{"type":"str","value":"."}]}],"prop":"filename","propout":"filetype","object":"msg","objectout":"msg","x":280,"y":820,"wires":[["8cb8c95c2f5a1591"]]},{"id":"044af6d97af553e4","type":"link in","z":"c6f2a894be05d857","g":"fee0b4a8fff9f4aa","name":"link in 5","links":["83477da8696ae6e7"],"x":125,"y":820,"wires":[["6eabd7a88e3863d3"]]},{"id":"264eb6e2f10c1ab5","type":"link out","z":"c6f2a894be05d857","g":"fee0b4a8fff9f4aa","name":"link out 6","mode":"link","links":["e95c6d9464521102"],"x":875,"y":820,"wires":[]},{"id":"c9930135726cf256","type":"group","z":"c6f2a894be05d857","g":"c0f2a076e4449f10","name":"Send the images to the correct section of the dashboard","style":{"label":true},"nodes":["ecf3cb2b1bc5096e","0629532fdd62fd03","3a790fd52e77cb43","3613df20a3a361e2","e95c6d9464521102","2728c1ee286a404b"],"x":84,"y":879,"w":892,"h":162},{"id":"ecf3cb2b1bc5096e","type":"ui_template","z":"c6f2a894be05d857","g":"c9930135726cf256","group":"8c5b99709c90620a","name":"Display the image on the Dashboard","order":1,"width":0,"height":0,"format":"<!DOCTYPE html>\n<html>\n<head>\n<style>\ndiv.parent {\n position: relative;\n height: 200px ;\n //width: 600px;\n}\ndiv.absolute {\n position: absolute;\n width: 100%;\n bottom: 0px;\n} \nimg{\n border-radius: 10px;\n}\n\n</style>\n</head>\n<body>\n <div class=\"parent\">\n <div class=\"relative\" >\n \n <img src= \"\" alt=\"Image loaded from the filestore\" style=\"width:100%\"><br>\n </div>\n </div>\n</body>\n</html>\n\n","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","className":"","x":750,"y":920,"wires":[["2728c1ee286a404b"]]},{"id":"0629532fdd62fd03","type":"ui_template","z":"c6f2a894be05d857","g":"c9930135726cf256","group":"8c5b99709c90620a","name":"Display the image on the Dashboard","order":4,"width":3,"height":4,"format":"<!DOCTYPE html>\n<html>\n<head>\n<style>\ndiv.parent {\n position: relative;\n height: 200px ;\n //width: 600px;\n}\ndiv.absolute {\n position: absolute;\n width: 100%;\n bottom: 0px;\n} \nimg{\n border-radius: 10px;\n}\n\n</style>\n</head>\n<body>\n <div class=\"parent\">\n <div class=\"relative\" >\n \n <img src= \"\" alt=\"Image loaded from the filestore\" style=\"width:100%\"><br>\n </div>\n </div>\n</body>\n</html>\n\n","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","className":"","x":750,"y":960,"wires":[["2728c1ee286a404b"]]},{"id":"3a790fd52e77cb43","type":"ui_template","z":"c6f2a894be05d857","g":"c9930135726cf256","group":"8c5b99709c90620a","name":"Display the image on the Dashboard","order":5,"width":3,"height":4,"format":"<!DOCTYPE html>\n<html>\n<head>\n<style>\ndiv.parent {\n position: relative;\n height: 200px ;\n //width: 600px;\n}\ndiv.absolute {\n position: absolute;\n width: 100%;\n bottom: 0px;\n} \nimg{\n border-radius: 10px;\n}\n\n</style>\n</head>\n<body>\n <div class=\"parent\">\n <div class=\"relative\" >\n \n <img src= \"\" alt=\"Image loaded from the filestore\" style=\"width:100%\"><br>\n </div>\n </div>\n</body>\n</html>\n\n","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","className":"","x":750,"y":1000,"wires":[["2728c1ee286a404b"]]},{"id":"3613df20a3a361e2","type":"switch","z":"c6f2a894be05d857","g":"c9930135726cf256","name":"Send the image to the correct section of the dashboard","property":"filename","propertyType":"msg","rules":[{"t":"eq","v":"ff-logo-wordmark-light_4x.png","vt":"str"},{"t":"eq","v":"screen-pseudo-overview-2QvTVle3Mr-384.avif","vt":"str"},{"t":"eq","v":"nr-image-1.png","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":370,"y":960,"wires":[["ecf3cb2b1bc5096e"],["0629532fdd62fd03"],["3a790fd52e77cb43"]]},{"id":"e95c6d9464521102","type":"link in","z":"c6f2a894be05d857","g":"c9930135726cf256","name":"link in 6","links":["264eb6e2f10c1ab5"],"x":125,"y":960,"wires":[["3613df20a3a361e2"]]},{"id":"2728c1ee286a404b","type":"link out","z":"c6f2a894be05d857","g":"c9930135726cf256","name":"link out 7","mode":"link","links":["d4c41d5c9f332ba4"],"x":935,"y":960,"wires":[]},{"id":"8c5b99709c90620a","type":"ui_group","name":"Default","tab":"4c70ce602964b5fb","order":1,"disp":false,"width":"6","collapse":false,"className":""},{"id":"4c70ce602964b5fb","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false},{"id":"806b98a5bdf7ceea","type":"group","z":"c6f2a894be05d857","g":"c0f2a076e4449f10","name":"Output a debug once all images have been processed","style":{"label":true},"nodes":["d4c41d5c9f332ba4","b40f5d5e5df0074d","f2f386a2615e5698"],"x":74,"y":1059,"w":392,"h":82},{"id":"d4c41d5c9f332ba4","type":"link in","z":"c6f2a894be05d857","g":"806b98a5bdf7ceea","name":"link in 7","links":["2728c1ee286a404b"],"x":115,"y":1100,"wires":[["b40f5d5e5df0074d"]]},{"id":"b40f5d5e5df0074d","type":"join","z":"c6f2a894be05d857","g":"806b98a5bdf7ceea","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":200,"y":1100,"wires":[["f2f386a2615e5698"]]},{"id":"f2f386a2615e5698","type":"debug","z":"c6f2a894be05d857","g":"806b98a5bdf7ceea","name":"debug 141","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":350,"y":1100,"wires":[]},{"id":"b58daed1ee453873","type":"group","z":"c6f2a894be05d857","g":"c0f2a076e4449f10","name":"Inject the image files' names","style":{"label":true},"nodes":["9cf7532041d938d2","0ec6e6d3e7b31ad7","b669ea3caf594f9a","bca6faef579bc33d","89abee9a3f6cd7e5"],"x":74,"y":539,"w":782,"h":122},{"id":"9cf7532041d938d2","type":"inject","z":"c6f2a894be05d857","g":"b58daed1ee453873","name":"Inject","props":[],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","x":170,"y":580,"wires":[["89abee9a3f6cd7e5"]]},{"id":"0ec6e6d3e7b31ad7","type":"split","z":"c6f2a894be05d857","g":"b58daed1ee453873","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":730,"y":580,"wires":[["b669ea3caf594f9a"]]},{"id":"b669ea3caf594f9a","type":"link out","z":"c6f2a894be05d857","g":"b58daed1ee453873","name":"link out 4","mode":"link","links":["bee4039410549ec8"],"x":815,"y":580,"wires":[]},{"id":"bca6faef579bc33d","type":"ui_ui_control","z":"c6f2a894be05d857","g":"b58daed1ee453873","name":"Update images on dashboard open","events":"connect","x":240,"y":620,"wires":[["89abee9a3f6cd7e5"]]},{"id":"89abee9a3f6cd7e5","type":"change","z":"c6f2a894be05d857","g":"b58daed1ee453873","name":"Image file names as an array","rules":[{"t":"set","p":"payload","pt":"msg","to":"[\"ff-logo-wordmark-light_4x.png\",\"screen-pseudo-overview-2QvTVle3Mr-384.avif\",\"nr-image-1.png\"]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":540,"y":580,"wires":[["0ec6e6d3e7b31ad7"]]},{"id":"c65a9370f1fec257","type":"group","z":"c6f2a894be05d857","name":"Chart showing CPU load","style":{"label":true},"nodes":["4b5271c11b0b1bba","5bf4c21f882eccd0","775403922e7c51f4","3789d7b7f40e8596","3be771b04a805b19","96a1d087230c4631","b82cd8fb933d1f1b"],"x":54,"y":1179,"w":1012,"h":122},{"id":"4b5271c11b0b1bba","type":"inject","z":"c6f2a894be05d857","g":"c65a9370f1fec257","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"1","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":170,"y":1220,"wires":[["775403922e7c51f4"]]},{"id":"5bf4c21f882eccd0","type":"ui_chart","z":"c6f2a894be05d857","g":"c65a9370f1fec257","name":"","group":"8c5b99709c90620a","order":2,"width":3,"height":4,"label":"CPU Load %","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"60","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":790,"y":1220,"wires":[["3789d7b7f40e8596"]]},{"id":"775403922e7c51f4","type":"Loadavg","z":"c6f2a894be05d857","g":"c65a9370f1fec257","name":"","x":320,"y":1220,"wires":[["3be771b04a805b19"]]},{"id":"3789d7b7f40e8596","type":"debug","z":"c6f2a894be05d857","g":"c65a9370f1fec257","name":"debug 142","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":950,"y":1220,"wires":[]},{"id":"3be771b04a805b19","type":"change","z":"c6f2a894be05d857","g":"c65a9370f1fec257","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.loadavg[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":1220,"wires":[["b82cd8fb933d1f1b"]]},{"id":"96a1d087230c4631","type":"ui_gauge","z":"c6f2a894be05d857","g":"c65a9370f1fec257","name":"","group":"8c5b99709c90620a","order":3,"width":3,"height":4,"gtype":"gage","title":"CPU Load","label":"units","format":"%","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","diff":false,"className":"","x":790,"y":1260,"wires":[]},{"id":"b82cd8fb933d1f1b","type":"calculator","z":"c6f2a894be05d857","g":"c65a9370f1fec257","name":"","inputMsgField":"payload","outputMsgField":"payload","operation":"mult","constant":"100","round":true,"decimals":0,"x":640,"y":1220,"wires":[["96a1d087230c4631","5bf4c21f882eccd0"]]}]
I have also included some simple dashboard elements you can view alongside the images. Let's take a look at the dashboard:
If you import these flows into Node-RED, you should see the images automatically loaded into the dashboard when you view it. You can also replace the URLs and file paths to try using some different images if you'd like to.
# More things to try
In this example, the images are static but it's simple to load images depending on the state of the flow. As mentioned in this article's introduction, you could display context aware images guiding the user of the dashboard to a specific location on a map, to complete a maintenance task. If you're interested in seeing examples of dynamic image loading please comment below.
# Conclusion
Images can add a lot of value to dashboards, but depending on how you host a given Node-RED instance it can be challenging to ensure the correct images are shown, especially when working with your flows in a DevOps pipeline. The techniques I've discussed above allow you to use images in dashboards, even in containerised environments.
I'd love to hear your comments and suggestions on this article. please tell us what you think about this article, and how you might use these techniques in the comments section below.
Comments:
Written By:
Published on:
Recommended Articles:
- How to Use Private Custom Nodes in FlowFuse?
- Custom Vuetify components for Dashboard 2.0
- Updating our branding across GitHub, npm and Dockerhub
- How ChatGPT improves Node-RED Developer Experience
- Share & Preview Flows on flows.nodered.org