Skip to content

Instantly share code, notes, and snippets.

@mohnen
Last active December 11, 2023 22:32
Show Gist options
  • Save mohnen/6923d5eb2e4547bb7e5bd90546d2ee80 to your computer and use it in GitHub Desktop.
Save mohnen/6923d5eb2e4547bb7e5bd90546d2ee80 to your computer and use it in GitHub Desktop.
Changing Favicons for node-red Dashboards

Changing Favicons for node-red Dashboards

Dashboards created with node-red-dashboards all have the same favicon

icon192x192

You can easily change this by changing the icons in the .node-red/node-modules/node-red-dashboard/dist, but this change will be lost the next time you update node-red-dashboard.

To get a permanent change, add your icon as files icon64x64.png, icon120x120.png, and icon192x192.png to a folder of your choice, e.g. /home/nodereduser/.node-red/icons, where nodereduser is the user executing node-red.

Then stop node-red and add this to .node-red/settings.js

  • Updated Version w/o full path
  ui: {
      middleware: function (req, res, next) {
        if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) {
          res.sendFile(path.resolve(path.join(__dirname, 'icons', req.url)))
        } else {
          next()
        }
     }
  },
  • Old Version
ui: {
      middleware: function (req, res, next) {
        path = require('path')
        if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) {
          res.sendFile(path.resolve(path.join('/home/nodereduser/.node-red/icons', req.url)))
        } else {
          next()
        }
      }
    },

Start node-red again, clear caches on all clients, and enjoy your changes favicons.

@mohnen
Copy link
Author

mohnen commented Jan 5, 2021

Hi Alberto,

did you replace '/home/nodereduser/.node-red/icons with the corresponding path in your installation?
If you send me the exact code you use, I can have a look

Thanks, Markus

@tou-ink
Copy link

tou-ink commented Jan 5, 2021

Hi Mohnen,
thank you for your assistance!

I use the deafult path in my settings.js

ui: { middleware: function (req, res, next) { path = require('path') if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/home/pi/.node-red/icons', req.url))) } else { next() } } },

By browser I see the correct Icons in the UI dashboard page but I have an error with ui_table. (If I must change some other settings, I'll do).
I think the problem is where the node-red-node-ui-table take the path but I don't know.

BR,
Alberto

@mohnen
Copy link
Author

mohnen commented Jan 5, 2021

Hm, I will need to setup this scenario with node-red-node-ui-table to have a look at this.
I cant do this right now, it might take some time for me to answer again.

@nextor89
Copy link

Hi,
I have a problem with custom icon and node-red-node-ui-table .

if I use your code the node has a warning:
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string.

Do you have a solution for this ?

BR,
Alberto

Just add path: "ui" inside ui dict:
ui: { middleware: function (req, res, next) { path = require('path') if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/home/nodereduser/.node-red/icons', req.url))) } else { next() } }, path: "ui" },

@Ataraxiall
Copy link

Hi,
I previously had this configuration to enter the ui directly by putting http://ip:1880 instead of http:// ip:1880/ui
ui: { path: "" },
Can this code be adapted to place the favicons and keep my configuration?

Thanks!

@mohnen
Copy link
Author

mohnen commented Feb 2, 2021

@Ataraxiall: Did you try to adopt @nextor89's suggestion?

ui: { middleware: function (req, res, next) { path = require('path') if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/home/nodereduser/.node-red/icons', req.url))) } else { next() } }, path: "" },

@Ataraxiall
Copy link

@Ataraxiall: Did you try to adopt @nextor89's suggestion?

ui: { middleware: function (req, res, next) { path = require('path') if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/home/nodereduser/.node-red/icons', req.url))) } else { next() } }, path: "" },

That give me a error:
ReferenceError: path is not defined
at middleware (/root/.node-red/settings.js:113:24)

thanks

@DonatoD
Copy link

DonatoD commented May 14, 2021

I'm not succeeding in doing it. I use windows 10 with node-red v1.2.9.
This is the code I use in setting.js
const path = require('path')
....
module.exports = { ...... ui: { middleware: function (req, res, next) { if (['\\icon64x64.png', '\\icon120x120.png', '\\icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join("C:\\Users\\Me\\.node-red", 'icons', req.url))) } else { next() } } }, ...... }
Thanks

@mohnen
Copy link
Author

mohnen commented May 14, 2021 via email

@DonatoD
Copy link

DonatoD commented May 14, 2021

Thanks, I even tryed leaving
if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url))
and yes, c:\users\me\.node-red\icons does exist.
What is strange is that I even tryed directly changing the icon files directly in" c:\users\me\.node-red\node-modules\node-red-dashboard\dist", but nothing happens. It continues to show the default imagine.
I deleted the chrome's cache starting from the beginning, but nothing. Now I'm googling for other temporary files to delete!

@DonatoD
Copy link

DonatoD commented May 14, 2021

Some update:

  1. Probably I misunderstood. I thought this would have changed even the icons for the programming environment (127.0.0.1:1880) and login format, not only the one for the dashboard page. So, I quickly verified that the fist ones hadn't changed. Forgive me!
  2. Now, clarified this, if I directly change the icon inside "C:\users\Me\.node-red\node-modules\node-red-dashboard\dist" it works.
    but if I add the code inside the settings.js file, it doesn't. the problem is probably this line:
    if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url))
    if I change / with \\ or delete it, then the default icon is loaded (the one in node-red-dashboard\dist). But if I leave the / character as posted, than this is the error I get:
ReferenceError: path is not defined
    at middleware (C:\Users\Me\.node-red\settings.js:114:27)
    at Layer.handle [as handle_request] (C:\Users\Me\AppData\Roaming\npm\node_modules\node-red\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\Me\AppData\Roaming\npm\node_modules\node-red\node_modules\express\lib\router\index.js:317:13)
    at C:\Users\Me\AppData\Roaming\npm\node_modules\node-red\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (C:\Users\Me\AppData\Roaming\npm\node_modules\node-red\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Users\Me\AppData\Roaming\npm\node_modules\node-red\node_modules\express\lib\router\index.js:275:10)
    at compression (C:\Users\Me\.node-red\node_modules\compression\index.js:220:5)
    at Layer.handle [as handle_request] (C:\Users\Me\AppData\Roaming\npm\node_modules\node-red\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\Me\AppData\Roaming\npm\node_modules\node-red\node_modules\express\lib\router\index.js:317:13)
    at C:\Users\Me\AppData\Roaming\npm\node_modules\node-red\node_modules\express\lib\router\index.js:284:7

@mohnen
Copy link
Author

mohnen commented May 14, 2021 via email

@DonatoD
Copy link

DonatoD commented May 16, 2021

Thanks so much, that was the problem. Now it works perfectly. Great.
May I ask you two more suggestions on this topic?

  1. There is a way to even change the login icon, at least? (I secured node-red with authentication)
  2. I use two instances using the same settings.js but running them specifying the flow json file name as option. There is a way to load two different icons, depending on which instance (flows.json) is running? It would be awesome have the icons in the same folder with two different names.
    Thanks

@mohnen
Copy link
Author

mohnen commented May 17, 2021 via email

@DonatoD
Copy link

DonatoD commented May 17, 2021

  1. I mean this form
    image
  2. Ok. I was thinking to something like that: let's picture I have 2 set of icons: one for Aflows.json and one for Bflow.json. Since at this step of the settings.js I already know which flows.json file it has to be load, I could instruct the program to load the appropriate set of icone and pass it as icon64x64.png - icon120x120.png - icon192x192.png as requested. I know that translate it in a readable and working code is a different things, but if you think it could be possible and give me some tips, I could make some try.
    Thanks again so much for all the support

@mohnen
Copy link
Author

mohnen commented May 18, 2021 via email

@mohnen
Copy link
Author

mohnen commented May 18, 2021 via email

@DonatoD
Copy link

DonatoD commented May 18, 2021

Item #1: I made several test but nothing. Following are the main ones:
.......
} else if (['/**red/images/node-red-256.png'].includes(req.url)){
res.sendFile(path.resolve(path.join('C:\\Users\\Me\.node-red\\icons', req.url)))
//res.sendFile('C:\\Users\\Me\.node-red\\icons\\node-red-256.png')
//res.sendFile('C:\\Users\\Me\.node-red\\icons\')
} else {
next()
} ,
......
From what i understand, if I'm not wrong, the problem could be that this login form doesn't come with the ui dashboard, as it is related to login for the working environment. So, maybe the ui section is not the right place where to put it. What do you think?

Item #2: Yes, I thought to something like that, but I don't know how passing the correct set of Icons, since they are named differently: icon_A_64x64.png ... (for Aflows.json) and icon_B_64x64.png .... (for Bflows.json)

@jackc94
Copy link

jackc94 commented Apr 23, 2023

@mohnen I am trying to apply this to my node-red Dashboard hosted in Docker... should this work in your opinion?

ui: { middleware: function (req, res, next) { if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/data/icons', req.url))) } else { next() } } },

Or should I just need:

ui: { middleware: function (req, res, next) { if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/icons', req.url))) } else { next() } } },

This is the docker-compose.yml:

version: "3.7" services: node-red: image: nodered/node-red:latest container_name: node-red environment: - TZ=Europe/London network_mode: host restart: unless-stopped volumes: - ~/.node-red:/data

@mohnen
Copy link
Author

mohnen commented Apr 23, 2023

I'm sorry, I don't know. Its been a long time since I last used node-red

@jackc94
Copy link

jackc94 commented Apr 24, 2023

@mohnen I am trying to apply this to my node-red Dashboard hosted in Docker... should this work in your opinion?

ui: { middleware: function (req, res, next) { if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/data/icons', req.url))) } else { next() } } },

Or should I just need:

ui: { middleware: function (req, res, next) { if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/icons', req.url))) } else { next() } } },

This is the docker-compose.yml:

version: "3.7" services: node-red: image: nodered/node-red:latest container_name: node-red environment: - TZ=Europe/London network_mode: host restart: unless-stopped volumes: - ~/.node-red:/data

I managed to work this out myself for those using Docker deployment of node-red:

Find the ui section of the settings.js file (quite near the end, under Node Settings) and amend as follows (obviously replacing with your file path):

ui: { path: "/", middleware: function (req, res, next) { path = require('path') if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) { res.sendFile(path.resolve(path.join('/data/dashboard/icons', req.url))) } else { next() } } },

@T-21
Copy link

T-21 commented May 25, 2023

This is the method I used, I altered the snippet a little bit to make it work inside docker.

Custom Node-Red favicons using docker:

  1. Navigate to the 'data' directory of your Node-Red container

  2. create a folder for the custom icon files (name it 'custom_icons'):

    mkdir custom_icons

  3. Place the .png files into the created path

  4. Edit settings.js.

  5. Go all the way to the bottom of the file and find the commented out "//ui:" part. Directly under it, past the following code:

     ui: {
     path: "/ui/",
     middleware: function (req, res, next) {
         var path = require('path');
         if (['/icon64x64.png', '/icon120x120.png', '/icon192x192.png'].includes(req.url)) {
     	    res.sendFile(path.resolve(path.join('/data/custom_icons', req.url)));
         } else {
         next();
         }
     }
     },
    
  6. Check the path on line 6 and make sure it matches the path of your custom_icons folder, if not, adjust accordingly.

Save the file and restart Node-Red to see the icons

@Lorilatschki
Copy link

@T-21 this worked on my site as well! Thanks for the adaption regarding running node-red inside docker!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment