Repository navigation
feat: script and style support in the ui-template code editor - #2291
Merged
n-lark merged 3 commits intoOct 21, 2026
Merged
Conversation
Contributor
Author
Contributor
Author
|
better demo: ui-template-vue-vuetify-demo.mp4 |
n-lark
approved these changes
Oct 14, 2026
n-lark
left a comment
Contributor
There was a problem hiding this comment.
Looks good minor nit - tested the following:
Tested on: Node-RED 3.1.15 (Monaco 0.38), 4.1.16 (Monaco 0.52), 5.0.4 (Monaco 0.55) and 5.0.8 (main, Monaco 0.57, with #5994).
3.1.15, 4.1.16 and 5.0.4 (without #5994):
- Same behaviour as #2290: dashboard, completion, hover, expand editor, scope switching, Done and Deploy all work
-
vue-script.mjsnever loads - HTML completion works on older Monaco (3.1 and 4.1)
- No console errors
5.0.8 (with #5994):
- All #2290 checks still pass
-
<script>completion, including typedthis(data, computed, methods,msg,send,$socket, etc.) - Syntax errors and CSS errors are flagged
-
<style>CSS completion - No false errors on the test template or on 18 of the 19 docs examples
- Library preview editor uses
vue-sfc - Hidden editor models are cleaned up on Done and Cancel
- Typing stays fast on a 156 KB template
Steve-Mcl
force-pushed
the
feat/ui-template-script-style
branch
4 times, most recently
from
October 17, 2026 08:00
f480403 to
ba79ea6
Compare
Contributor
Author
|
Fixed in c150d61 - a comment after |
Contributor
Author
|
Code editor errors in the template now mark the node as invalid, like the Function node. |
2 of 6 tasks
Builds on node-red/node-red#5994, which adds JavaScript and CSS support to <script> and <style> blocks in Node-RED's HTML editors and lets other HTML-like languages opt in. This opts the ui-template's vue-sfc language in and adds what is specific to Dashboard: the type of `this`. - Component scripts (a single `export default { ... }`) are wrapped in the hidden copy so `this` in data, computed, methods, watch, mounted and unmounted knows the component's members and what Dashboard adds (send, submit, msg, value, id, props, $socket, $store, $router, $vuetify, ...) - Other scripts, which Dashboard runs inside mounted, get the same `this` - Only loaded when Node-RED provides registerEmbeddedLanguages, so older Node-RED is unaffected - The plugin uses Node-RED's registerHTMLLanguage when present, which also maps the worker, instead of its own registration and worker shim
The editor only treated a script as a component when nothing but `}` or `;` followed the closing brace, so a trailing comment wrapped it as raw JavaScript and flagged `export default`. Dashboard ignores comments here, so the editor now skips // and /* */ comments after the component as well as before it.
The edit dialog already counted editor errors into noerr on save, but noerr wasn't a node property, so nothing was validated and the node never showed an error. Declare it with a validator so errors in the template show the usual invalid node marker, as the Function node does.
n-lark
force-pushed
the
feat/ui-template-script-style
branch
from
October 21, 2026 15:04
24d8953 to
6fd89ad
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Description
Builds on #2290 and node-red/node-red#5994. Related to node-red/nr-monaco-build#9 and node-red/nr-monaco-build#18.
Summary
#2290 gives ui-template Vue and Vuetify editing.
Inside
<script>and<style>it only highlights code. node-red/node-red#5994 adds JavaScript and CSS support for those blocks to Node-RED's HTML editors, and an API (RED.editor.codeEditor.monaco.registerEmbeddedLanguages) so other HTML-like languages can opt in.This PR opts ui-template's
vue-sfclanguage in, and adds the parts that are specific to Dashboard: the type ofthis.With a Node-RED version that includes node-red/node-red#5994, the ui-template editor gets:
<script>: JavaScript completion, hover info, parameter hints, go to definition and error checking.thisknows the component:data,computedandmethods, plus what Dashboard adds:this.send(),this.submit(),this.msg,this.value,this.id,this.props,this.$socket,this.$store,this.$router,this.$vuetifyand the usual Vue instance members.<style>: CSS checking. With feat: expose the CSS and HTML language workers node-red/nr-monaco-build#18 in Node-RED's Monaco, also CSS completion, hover and colour previews.On older Node-RED nothing changes: ui-template keeps the Vue/Vuetify support from #2290, and this code isn't even loaded.
How it works
Node-RED does the heavy lifting: a hidden copy of each block that Monaco's TypeScript and CSS workers answer for, mapped back onto the editor. Dashboard only tells it how to read a ui-template script, matching how Dashboard runs it (
ui/src/widgets/ui-template/UITemplate.vue,ui/src/util/vue.acorn.js):export default { ... }) is rewritten in the hidden copy asexport default __uiTemplate({ ... }). A small type declaration then givesthisthe right type indata,computed,methods,watch,mountedandunmounted.mounted, so it's wrapped in a function whosethisis the component.Files:
resources/vue-editor/vue-script.mjs(new, ~145 lines): thethistype declarations, the wrapper, and the call toregisterEmbeddedLanguages. The wrapper's helper names are hidden from completions, and$members sort after the component's own.resources/vue-editor/vue-sfc.mjs: loadsvue-script.mjsonly when Node-RED providesregisterEmbeddedLanguages.nodes/plugins/vue-editor.html: uses Node-RED'sregisterHTMLLanguagewhen present, which also maps the language to the html worker. Older Node-RED keeps feat: Vue and Vuetify editing in the ui-template code editor #2290's own registration and worker mapping.docs/en/nodes/widgets/ui-template.md: one more bullet in the Code Editor section.TypeScript details I hit, recorded in the type declarations:
created, which Dashboard ignores with a console warning) made TypeScript give up and typethisasany. So the options type allows other keys and doesn't warn about them.thisdirectly onwatch/mounted/unmountedbroke inference whenwatchcomes beforemethods. They takethisfrom the surroundingThisType, like Vue's own types.Testing
test/resources/vue-script.spec.js(8): component vs raw detection matching Dashboard's parser, the wrapper's insertions, the type declarations, andactivate()with and without Node-RED's API. The full suite passes (255) and lint is clean.this.in a component listscount, doubled, go, id, items, msg, other, props, send, submit, value..., andthis.countisnumber. Leaving out each option in turn (data/computed/watch/methods/mounted) keeps the typing.this.lists the component's own members first, then Dashboard's;this.send(shows its signature and description;notDefined()is underlined on the right line;this;<style>;vue-script.mjsisn't requested, feat: Vue and Vuetify editing in the ui-template code editor #2290's Vue/Vuetify support works as before, no console errors.Related Issue(s)
#2290
node-red/node-red#5994
node-red/nr-monaco-build#9
node-red/nr-monaco-build#18
Checklist
flowforge.yml?FlowFuse/helmto update ConfigMap TemplateFlowFuse/CloudProjectto update values for Staging/ProductionLabels
area:migrationlabel