# Uibuilder: Component Design + Example Components

**URL:** https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293
**Category:** Developing Nodes
**Tags:** uibuilder
**Created:** [1 September 2020 10:12 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293 "2020-09-01T10:12:56Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [1 September 2020 10:12 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/1 "2020-09-01T10:12:56Z")

</div>

Hi all, this topic is to capture ideas and decisions regarding the design of a VueJS component standard for uibuilder.

uibuilder VueJS components will be standard pieces of front-end code with an agreed msg schema for communications from/to Node-RED. They will be the uibuilder equivalent of Dashboard widgets. However, where those send the _code_ as well as the data from Node-RED to the front-end, uibuilder components will only send _data_ since the code is developed using standard web development methods.

Here are my starter requirements for uibuilder VueJS components - everything is open for discussion though so if you disagree, please chip in and explain why and what might be better:

1. Each component (or component set) must be installable via npm (e.g. using the uibuilder library manager or manual install into the `userDir` folder)

2. Components npm modules should be named `node-red-contrib-uib-xxxxx` - the components themselves should be named in line with VueJS naming conventions and should clearly identify what they do in the name.

3. Component npm modules _should_ have the "uibuilder" tag.

4. Component npm modules should **NOT** have a "node-red" tag (so that they don't confusingly appear in the Node-RED flows library) - after all, these are not Node-RED extensions and could be used outside of Node-RED.

5. Component npm modules **MUST** have a peer dependency of "node-red-contrib-uibuilder" listed in their package.json files.

6. Component npm modules _should_ identify the versions of VueJS they will work with.

7. uibuilder components **MUST** be usable with or without a build step.

8. Any JavaScript must be self isolating (wrapped in an anonymous, self-executing function).

9. Components must have suitable documentation including a schema description of the `msg` (or msgs) required.

10. Components _should_ be listed in the component index (to be created). This index may in the future auto-discover components based on the agreed component naming and a "uibuilder" tag in the npm module.

11. Components _should_ **not** assume that inputs are in any way correct or safe.

12. Components must take note of the uibuilder v3 proposed `msg.auth` schema that will be used for exchange of authentication/authorisation information.

The critical part of any uibuilder component will be the schema that describes how communications between Node-RED and your front-end happen and in what format.

In general, uibuilder VueJS components should not need a new Node-RED Node since all that is required is to send an appropriate msg to the front-end. It is currently expected that all communication happens via the uibuilder node instance. If we come across a situation that needs something different, we will need to have a separate discussion since it is possible that changes to uibuilder itself might be needed.

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [1 September 2020 10:31 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/2 "2020-09-01T10:31:21Z")

</div>

I have been working on components via a http-in/response node and serving the component via template nodes when using vuejs.

Meaning: the index.js requests components that are being served via node-red/templates, no dependencies on external files and everything can be managed within node-red (a template node is a component)

 ![Screenshot 2020-09-01 at 12.25.01](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/e/4e39272f1454aee1353466e6da1f9d2534feeb3f.jpeg)

In short, i am not in favor of all these stringent rules if it takes the current functionality away (ie. force vuejs), i use uibuilder also with vanilla js for example.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [1 September 2020 10:41 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/3 "2020-09-01T10:41:32Z")

</div>

Hi,

Sorry, I should have made that more clear in my first post. There is no intention to take anything away from uibuilder. You will still be able to use any framework you like (or no framework at all).

Indeed, I'd be delighted to start a discussion about components for other frameworks too as the same principles can apply.

Also, the availability of components won't make any difference to what you are doing other than to possibly identify some communications standards that might be helpful to you in the future.

To clarify then. uibuilder components are designed to make things easier for Node-RED users who might not have the knowledge to create complex front-end user interfaces. They are optional extensions to how uibuilder can be used, making the ui build easier. In reality, they are simply standard bits of front-end code with an agreed communications schema that can be reused wherever and whenever you like. Indeed, you could use them outside of Node-RED as well since I anticipate that most of them will be standard VueJS components.

> [@bakman2](#):
>
> the index.js requests components that are being served via node-red/templates, no dependencies on external files and everything can be managed within node-red (a template node is a component)

I like this as another option! It would be great to see this written up somewhere. Either in the flows library or as a WIKI entry on the uibuilder GitHub maybe?

_How are you managing the request in your front-end code? Would it benefit from being added as a standard function in uibuilderfe?_

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [5 September 2020 05:58 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/4 "2020-09-05T05:58:41Z")

</div>

> _How are you managing the request in your front-end code? Would it benefit from being added as a standard function in uibuilderfe?_

`httpVueLoader` requires a .vue file, basic idea is like:

```auto
'use strict';
var app1 = new Vue({
	el: '#app',
	components: {
		chart: httpVueLoader('http://10.0.0.6:1880/components/chart.vue'),
		pulldown: httpVueLoader('http://10.0.0.6:1880/components/pulldown.vue'),
	},
	data: {
		msg: '',
	},
	computed: {},
	methods: {},

	mounted: function () {
		uibuilder.start();
		var vueApp = this;

		uibuilder.onChange('msg', function (msg) {
			vueApp.msg = msg;
		});

	},
});

```

Where `http://10.0.0.6:1880/components/chart.vue` will be served via the http-in/template/response nodes  
For the http-in node I use:

 ![Screenshot 2020-09-05 at 07.47.32](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/1/f1ccdfc8bbb00cdcda413562e30beb5582810f0e.jpeg)

`msg.request.param` will become: `chart` and `pulldown` that can be used in a switch node, return the component from a template node.

I guess this is something that uibuilder could be able to serve somehow as well - like; if `.vue` request, send it (optionally) to one of the outputs of the uibuilder node, where one can capture it. But how to inject it back into uibuilder i dont know, as it needs to be served back somehow.

I could write up a wiki, but not sure about structure.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [5 September 2020 16:56 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/5 "2020-09-05T16:56:39Z")

</div>

Ah, OK, I think that is already in the WIKI.

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [5 September 2020 17:44 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/6 "2020-09-05T17:44:02Z")

</div>

Ok if it is great, I doubt it however, as it is not described how to serve dynamic files from within node-red; ie. template nodes. It works great and don't have to maintain files outside node-red.

Your original topic is about component design, which you can easily put in a template node like this.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [5 September 2020 22:45 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/7 "2020-09-05T22:45:10Z")

</div>

True. If you can add something to cover how you are delivering that from Node-RED, I can always tidy it up later so don't worry about the style.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [19 September 2020 11:46 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/8 "2020-09-19T11:46:26Z")

</div>

I now have an example component module on GitHub if anyone wants to try it.

> **[TotallyInformation/uibuilder-vuejs-component-extras](https://github.com/TotallyInformation/uibuilder-vuejs-component-extras)**
>
> A set of extra VueJS components designed to work with node-red-contrib-uibuilder though they should also work with other VueJS installations. - TotallyInformation/uibuilder-vuejs-component-extras

To be honest, I started this some while back but only just got round to uploading it - I can't remember the current status of the components and the documentation may still be a bit weak.

Anyway, just to let people know that I'll be using this module to try and create some VueJS components for use with uibuilder.

Read the README carefully for installation and usage.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [19 September 2020 19:28 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/9 "2020-09-19T19:28:01Z")

</div>

I've pushed some updates as well so that the gauge component now works - far from complete but it does work.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [20 September 2020 01:17 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/10 "2020-09-20T01:17:44Z")

</div>

Another update pushed.

See the examples for the gauge component - you will see the first examples of pushing data direct to the component so that you don't have to do anything in your HTML (eventually not in your js either as this will be folded into the uibuilderfe library).

All you need to do is set an ID on each component instance and then send the right data format through to the front-end.

The HTML can be as simple as:

```auto
<gauge ref="gauge1" />

```

> **[TotallyInformation/uibuilder-vuejs-component-extras](https://github.com/TotallyInformation/uibuilder-vuejs-component-extras/tree/master/gauge/examples/http-vue-loader)**
>
> A set of extra VueJS components designed to work with node-red-contrib-uibuilder though they should also work with other VueJS installations. - TotallyInformation/uibuilder-vuejs-component-extras

---

<div class="post-metadata">

### Author: ![alex88](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alex88/32/55523_2.png) [@alex88](https://discourse.nodered.org/u/alex88)
#### Post date: [20 September 2020 18:30 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/11 "2020-09-20T18:30:30Z")

</div>

This all looks incredibly interesting, however I am not sure how I test out what you have built?

Also, given my learning experience with uibuilder, I'm wondering how much benefit these nodes will provide if you know how to write the code for the component in the first place. I guess it will work really well for more complex components, right?

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [20 September 2020 19:40 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/12 "2020-09-20T19:40:59Z")

</div>

Well the idea is to provide components that will mirror some of those in Node-RED's Dashboard. So that you can quickly drop in a component reference and start sending data to it straight away.

At the moment, whenever you look at a Vue component, you have to work out how it has been packaged, what it's props are and how to use it. Fine if you are only using a few and are familiar with Vue. Not so good otherwise. While the uibuilder WIKI has some components documented, it is still daunting to set up for many people.

It gets worse if you want multiple components and/or multiple copies (instances) of components (e.g. multiple gauges on a page). Currently you have to hand-craft front-end javascript code to unpick data that is sent through and work out how to update the correct instance.

Once I (and hopefully others) start wrapping components for use in this way, you will have a very simple, standardised way to send data through to multiple component instances without any code required. There will also be standardised ways of getting data back to Node-RED again - have a look at the gauge .vue code for example and you will see an optional click handler that sends key event data back to Node-RED automatically when you click on the gauge (if you've turned on the flag).

What's more, there will be instructions on how to build new components that work in the same way so anyone with some Vue skills can write their own or wrap existing components.

And the icing on the cake will be a command that you can send from Node-RED that will return a msg containing the data schema and a link to the components documentation. So taking away any confusion about how to send data to the component.

Data-driven UI's are a real interest of mine and have been for years and I'm quite excited about this. I've been trying to work through the possibilities of how to make uibuilder easier for people to use and this feels like a real step forwards.

* * *

Testing does require some commitment at the moment. You need to manually install the extras node from GitHub to your userDir folder, restart Node-RED and then copy the html and js from the example files into a uibuilder instance.

The gauge component is the easiest one and the only one with the start of the standardised comms built in (currently in the index.js file).

Try adding a second gauge to the page with a different ref id and send data to both. I'll update the repo shortly with an example flow that you can import as well.

---

<div class="post-metadata">

### Author: ![alex88](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alex88/32/55523_2.png) [@alex88](https://discourse.nodered.org/u/alex88)
#### Post date: [20 September 2020 19:44 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/13 "2020-09-20T19:44:28Z")

</div>

Much clearer, thank you!

I'll try and carve out some time to test what you've done. It's sounds like the start of a beautiful thing!

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [20 September 2020 21:07 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/14 "2020-09-20T21:07:50Z")

</div>

The updates are loaded. Here is the example web page.

While this page uses some extra HTML, the minimal is: `<gauge ref="gauge1" />` nothing else needed.

 ![screencap](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/6/56c4efb20844970af820654e86ef4ceff5e794fa.gif)

---

<div class="post-metadata">

### Author: ![alex88](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alex88/32/55523_2.png) [@alex88](https://discourse.nodered.org/u/alex88)
#### Post date: [20 September 2020 21:20 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/15 "2020-09-20T21:20:31Z")

</div>

A picture says a thousand words.

This will be cool. Just need to get people behind it.

Wish I was better at Vue so I could build a component.... I guess a goal for next year... Ha ha!!!

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [20 September 2020 21:25 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/16 "2020-09-20T21:25:52Z")

</div>

> [@alex88](#):
>
> Wish I was better at Vue so I could build a component

Rome wasn't built in a day 🕶

Have a look at the gauge .vue file, you might be surprised just how simple it is. Even with the crud that is currently in it as I experiment with things.

I can tell you that I am _far_ from being any kind of Vue expert. I just about understand the basics.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [23 September 2020 21:23 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/17 "2020-09-23T21:23:18Z")

</div>

Check out the further example of these principles in another thread:

> [@\[uibuilder\] Easy toast notifications](https://discourse.nodered.org/t/uibuilder-easy-toast-notifications/33252):
>
> One of the issues that some people find when switching to uibuilder from Dashboard is that they are faced with writing more HTML/CSS/JavaScript front-end code than they may be used to (or comfortable with). I chose VueJS and bootstrap-vue as the default templates from v2 because I believe that they offer the most capability with the simplest learning curve and minimum "boilerplate" code. Even so, many things could be simpler still and I've been thinking about and [writing about](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293) this for some wh…

That shows how simple it is to have a zero-code user notification feature in uibuilder.

---

<div class="post-metadata">

### Author: ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)
#### Post date: [9 October 2020 20:45 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/18 "2020-10-09T20:45:39Z")

</div>

Hi Julian,  
Sorry to respond so late, but very busy period...  
But after all the work you have spent on this, it should really get more attention!

Just my personal opinion:

- Lots of users want to keep their ui layer separated from Node-RED. I can understand that, but personally I really like how it is currently fully integrated into the flow ...

- Currently all my ui nodes can be used similar to non-ui nodes:

- And I really like the integration of ui nodes with the flow, via input and output messages. When I saw that the first time a couple of years ago, I thought: that is a f\*cking brilliant idea...

Although I respect other opinions about this, I don't see myself replacing my current AngularJs dashboard by another dashboard that offers less integration. I just love the current concept, and that is why I love writing ui-nodes that fit into the concept.  
I hope you understand ...  
Bart

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [9 October 2020 23:04 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/19 "2020-10-09T23:04:39Z")

</div>

> [@BartButenaers](#):
>
> I would really be disappointed to see all that integration to disappear in the future.

I'm not trying to take away from things like Dashboard. uibuilder serves a different set of needs. There is plenty of room for both styles.

> [@BartButenaers](#):
>
> Installation and version checks via the _"Manage palette"_

That is certainly a weakness of the current version of uibuilder. The library manager doesn't have all of the features it needs. But just like the node-red palette manager, it is possible to enhance it.

> [@BartButenaers](#):
>
> Setup via config screen

Well, that is a matter of style. As you say, some prefer config panels and other people are happy with config files.

Actually, with the next step in uibuilder evolution, it might be possible to have the best of both worlds. By having pre-agreed data schemas, it would be possible to build nodes that control the front-end from node-red. Though you would still build the actual UI from code of course.

> [@BartButenaers](#):
>
> And I really like the integration of ui nodes with the flow, via input and output messages. When I saw that the first time a couple of years ago, I thought: that is a f\*cking brilliant idea...

I'm going to write about things I don't like about Dashboard - but I don't want people to think that means that I don't appreciate Dashboard and what it brings to Node-RED. Without it, the platform would be nowhere near as useful as it is. And without it, I wouldn't have been inspired to write uibuilder. And that someone could have designed and built something as powerful and useful as UI in so short a time was amazing & inspiring.

* * *

What I don't like about Dashboard (apart from Angular which I dislike on principle having tried to build things with it), is the way that code is sent from the server to the front-end. I find that inelegant. 😃 One of my drivers was to avoid that. With a data-driven interface, you have separation of concerns between the front-end code and the back-end data. Node-RED controls the data, you use standard web design tools for the front-end. Logic you can split however you want.

Plenty of other things to annoy one about Dashboard too. Lack of access to the full power of Angular for example. The inability to make use of optimisations via a build step.

And of course, the flip side of the fact that you don't need to be a dev in order to create a web layout is the lack of flexibility to create custom UI's.

So I hope that, between us, we've put both sides of the discussion.

> [@BartButenaers](#):
>
> I hope you understand ...

I do, you are happy to live with the limitations of a fixed grid layout and heavyweight comms pushing code to the front-end. I'm happy to use standard tools to have unlimited freedom to create any kind of data-driven UI with efficient, minimal data-exchange. 🤣

Each to their own and thank goodness that we have plenty of choice. A testament to the flexibility of Node-RED as a platform.

Julian.

---

<div class="post-metadata">

### Author: ![alex88](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/alex88/32/55523_2.png) [@alex88](https://discourse.nodered.org/u/alex88)
#### Post date: [11 October 2020 10:26 UTC](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293/20 "2020-10-11T10:26:44Z")

</div>

We are not talking about deprecating dashboard, right.

All my uibuilder webpages are and will be heavily depended on dashboard + many other nodes.

That's the beauty of the setup, surely.

@TotallyInformation, I expect you agree.

[Next page](https://discourse.nodered.org/t/uibuilder-component-design-example-components/32293.md?page=2)
