Create custom ui node in Dashboard 2

I want to create a custom ui node for Dashboard 2 in Node-RED.

Where can I include my HTML code to be displayed on the dashboard? Do I need to integrate the code into the html or js file? Or is it necessary to create a new file to integrate the code?

Does anyone have experience with creating a custom ui node, whether dashboard or dashboard 2?

Is there a difference between the structure of Dashboard and Dashboard 2?

Perhaps the docs would help: Building Third Party Widgets | Node-RED Dashboard 2.0

Also, you can look at the source of a contrib dashboard-2 node: GitHub - bartbutenaers/node-red-dashboard-2-ui-svg: A Node-RED UI node to show SVG drawings in Node-RED dashboard v2 It is a piece of work @BartButenaers is busy with but I tried it out and it does (of course) work.

Perhaps you can you can glean the necessary info from these 2 sources.


We have this example repo linked in the docs too: GitHub - FlowFuse/node-red-dashboard-2-ui-example: An example project for writing third-party nodes that integrate with Node-RED Dashboard 2.0 (this is what Bart started with when building out dashboard-2-ui-svg for what it's worth.

There is a difference between Dashboard 1.0 and 2.0 as the latter is VueJS-based, the former is AngularJS-based.

Please let me know if you hit any hurdles or issues with it as you're working on the nodes. Hopefully everything you need will be in the documentation.

1 Like

Also note that you can use the D2 ui-template node and put that in a subflow to build something close to a custom node. Also the subflow can can be converted into a custom node. There are still some issues with this workflow though. Hopefully those will be sorted out soon though.

Hi @greenDog,
Nice to see that people start developing ui nodes for Dashboard 2!

Some more details about the info the the others mentioned already above:

  1. Create a fork of the node-red-dashboard-2-ui-example repo into your own Github account.
  2. Go through all the files, and replace everywhere your own stuff (node name, and so on...). I would take my time for that, because if you forget it on one place you might have to do a lot of troubleshooting afterwards to find the root cause.
  3. Most of it is described as Steve mentioned here.
    Note: I created a pull request yesterday evening to add an extra step to the documentation to skip minification during the Vite build step. Otherwise you get unreadable minified frontend code, which is very hard to debug.
  4. Ask here for help if you are stuck :wink:

Good luck with it!!

1 Like

Isn't the build step creating a map file? That is the answer. That way you can have the efficiency of minified code but still get meaningful debug output.

Hey Julian,
Thank you for supporting dashboard D2, the biggest competitor of UIBUILDER :wink:

Well to be honest I didn't investigate this further. Because @joepavitt shared here that the ui example node had been generated using a template generator. I would expect that a template generator would generate the best optimal code, but I might have not interpreted this correctly.

I have quickly compared both solutions to provide unminified frontend code, and looks like you are right.

Option 1 - minify option

When using in my Vite config the minify option:

export default defineConfig({
    build: {
        minify: false

Then I get only 1 bundle file:


Which results in readable frontend code in my Chrome debugger, but stuff like comments are gone:

Option 2 - sourcemap option

When using in my Vite config the sourcemap option:

export default defineConfig({
    build: {
        sourcemap: true

Then I get an extra source map file, next to the bundle file:


Which results in readable frontend code in my Chrome debugger, identical to the one I have developed:

And I didn't have to tell my Chrome debugger to load the source map file. It all happened automatically in some or another way.


Based on the above comparision, I suggest to use (both in the ui example node and in the dashboard repos) the following build option:

export default defineConfig({
    build: {
        sourcemap: process.env.NODE_ENV === 'development'

Then we can easily activate the source maps via export NODE_ENV=development.
If this is ok for you Joe, I will update my pull request.

Thanks @TotallyInformation for sharing your thoughts!!

1 Like

Great find @BartButenaers - PR very welcome there

1 Like

Hey, I support the community, not only my own nodes. :slight_smile: In any case, I don't see them as direct rivals and it isn't my fault that some people prefer the seemingly BMW version (or is that Tesla) over the Ford Pickup Ute!

An annoying habit as my wife likes to point out :rofl:

That's right, all of the browsers will do that unless you turn off the option deliberately.

For what it is worth, in UIBUILDER, while I use Gulp & ESBUILD rather than Vite, I simply and automatically produce the unminified & minified versions with the maps. I also automatically produce ESM and IIFE versions so that people can use my front-end libraries either as modules or simply loaded into global via a link tag. Not sure whether that latter part applies to D2 but for UIBUILDER, it makes the libraries super-flexible. Which is, of course, one of the design principals of UIBUILDER :slight_smile:


I modified the original PR and created a new PR for the ui example node (to make sure we use the same mechanism in all dashboard related repos).

@joepavitt I think there is a step missing from the instructions on building the example ui node. It does not say to install vite. I initially installed it on Ubuntu using apt, but then the build failed with a core dump, so I removed that and instead ran
npm install vite
and now it does build. Is that the correct way to install it?

By the way, how should one pronounce vite?

It's listed as a dependency on the repository, so when you npm install the ui-example repository, it should get installed for you.

Although, following through our docs, that step isn't explicit. I'll get it added - PR opened: Add install instructions for developing locally by joepavitt · Pull Request #13 · FlowFuse/node-red-dashboard-2-ui-example · GitHub

1 Like

it sounds like veet - it's French for quickly/fast

Ah, I thought 'what is the point in installing it before I have built it?' so didn't install it until after I had built it. Trying to be too clever!

Oh, no that isn't it is it. It is the npm install after cloning the repo that is missing.

I am playing with the ui example node and notice that in the props passed to it there is a class property. Where does this come from? I can't see it in the example. I need to provide a class field in the node config, but don't know how this will interact with the one already in the props object.

Further to this I find that if I have an input field called class in the html file then it is ignored as far as props is concerned. props.class is always an empty string. I have had to call it myclass in the html file and pick that up in the node.

Possibly related, the ui-example node starts with

<!-- Component must be wrapped in a block so props such as className and style can be passed in from parent -->
    <div className="ui-example-wrapper">

I don't understand the comment, or what className is here.

I had updated my PR to create a map file. But I now see that I am not able anymore to add breakpoints in my Chrome developer tool. Not in the mapped code (Vue file), but also not in the minified code.

Do you have any tips?

That's odd, they work fine for me in my code. Do you have the Vue debugging extension installed? Or I wonder if you need to map your local code folder into the dev tools - that lets you do things like make CSS changes in the dev tools that persist in your code, I think it might help with js as well but I'm not sure.

1 Like