Skip to content

Instantly share code, notes, and snippets.

@mohnen
Last active December 11, 2023 22:32
Show Gist options
  • Select an option

  • Save mohnen/6923d5eb2e4547bb7e5bd90546d2ee80 to your computer and use it in GitHub Desktop.

Select an option

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.

@marttin-h

Copy link
Copy Markdown

Works perfect for UI in Desktop.
No change in Save to desktop in Android, favicon is blank .

@mohnen

mohnen commented Apr 3, 2020 via email

Copy link
Copy Markdown
Author

@marttin-h

Copy link
Copy Markdown

Yes, works after delete cache. Thanks

@tou-ink

tou-ink commented Jan 4, 2021

Copy link
Copy Markdown

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

@mohnen

mohnen commented Jan 5, 2021

Copy link
Copy Markdown
Author

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

tou-ink commented Jan 5, 2021

Copy link
Copy Markdown

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

mohnen commented Jan 5, 2021

Copy link
Copy Markdown
Author

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
Copy Markdown

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
Copy Markdown

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

mohnen commented Feb 2, 2021

Copy link
Copy Markdown
Author

@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
Copy Markdown

@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

DonatoD commented May 14, 2021

Copy link
Copy Markdown

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

mohnen commented May 14, 2021 via email

Copy link
Copy Markdown
Author

@DonatoD

DonatoD commented May 14, 2021

Copy link
Copy Markdown

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

DonatoD commented May 14, 2021

Copy link
Copy Markdown

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

mohnen commented May 14, 2021 via email

Copy link
Copy Markdown
Author

@DonatoD

DonatoD commented May 16, 2021

Copy link
Copy Markdown

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

mohnen commented May 17, 2021 via email

Copy link
Copy Markdown
Author

@DonatoD

DonatoD commented May 17, 2021

Copy link
Copy Markdown
  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

mohnen commented May 18, 2021 via email

Copy link
Copy Markdown
Author

@mohnen

mohnen commented May 18, 2021 via email

Copy link
Copy Markdown
Author

@DonatoD

DonatoD commented May 18, 2021

Copy link
Copy Markdown

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

jackc94 commented Apr 23, 2023

Copy link
Copy Markdown

@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

mohnen commented Apr 23, 2023

Copy link
Copy Markdown
Author

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

@jackc94

jackc94 commented Apr 24, 2023

Copy link
Copy Markdown

@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

T-21 commented May 25, 2023

Copy link
Copy Markdown

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
Copy Markdown

@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