[ANNOUNCEMENT] node-red-contrib-blockly version 2.1.0 & 2.2.0 & 2.3.0

Hi folks,

For the people that prefer programming graphically by dragging and dropping Blockly blocks (instead of typing Javascript code in a function node), node-red-contrib-blockly version 2.1.0 is now available in your palette.

Thanks to my Blockly partner in crime (@cymplecy) to test this new version!

Summary of the changes:

  1. Upgrade from Blockly 6.x to 10.x

    There were quite a lot of intermediate Blockly versions in between, but those were not relevant for us. Since they were mostly technical releases, to migrate Blockly from Javascript to Typescript.

  2. Ability to search blocks in the toolbox, to avoid having to search manually through all the available categories:


  3. A minimap view (in fullscreen mode) that shows an overview of your entire workspace, and which part of the workspace is currently being rendered on your screen:


    Note that this minimap should be activated explicit in the config node, if it needs to be shown:


Have fun with it!!


@BartButenaers Excellent work as always :slight_smile:


I'm encountering a problem (can't edit any Blockly) node on my main NR instance (works fine on my Win11 instance)

[edit] Uninstalling and re-installing seems to have cured it so just treating as a glitch in my matrix :slight_smile:

Carry on :slight_smile:

1 Like

when are you gonna fix it so it display correctly in dark mode?

I'm sure @BartButenaers would accept a PR from you contributing that fix to his (brilliant!) project!


its been that way for years now, i figured someone had already spoken up.

There are now some blockly theme plugins available. I tried last week to load them. But my entire worspace was messed up. Since I had not enough free time to found the root cause, I have removed my code for that again.

So unless somebody wants to contribute, it will stay like this for a while...

Since the backend part of the Blockly node was originally based on the core Function node, I try to keep both nodes in sync ones and a while. However I forgot to do that in release 2.1.0, so I published now version 2.2.0 to NPM.

Thanks again to @cymplecy for testing this one in a short notice!!

This new version contains following changes:

  1. The backend code has been synced with the core Function node of Node-RED version 3.1.0

  2. Similar to the core Function node, the Blockly node now also has a timeout field:


    This can be used to interrupt long running features.

    Note that - similar to the core Function node - intervals/timers/loops are unfortunately not interrupted!

  3. Similar to the core Function node, the Blockly node now also allows to get the path ((sub)flowId/nodeId) of this node:


    Example flow:

    [{"id":"69ee3af8e4d3d034","type":"inject","z":"c53e793dd2f3be09","name":"Start","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":370,"y":420,"wires":[["93eed59ecd84aac8"]]},{"id":"93eed59ecd84aac8","type":"Blockly","z":"c53e793dd2f3be09","func":"msg['payload'] = node.path;\nnode.send([msg]);\n\nnode.path;\n","workspaceXml":"<xml xmlns=\"https://developers.google.com/blockly/xml\">\n  <block type=\"node_object_set\" id=\"{HhMU.r!93@,X*U]cnOO\" x=\"-737\" y=\"-687\">\n    <value name=\"object_field\">\n      <shadow type=\"node_msg\" id=\"DSrocV,iepv#xI5CNnR*\"></shadow>\n    </value>\n    <value name=\"field_name\">\n      <shadow type=\"text\" id=\"QY[2X`uT|j(|9hEjRP@i\">\n        <field name=\"TEXT\">payload</field>\n      </shadow>\n    </value>\n    <value name=\"value_field\">\n      <shadow type=\"text\" id=\"#!`_0-/,RL$v7g2V3k5[\">\n        <field name=\"TEXT\">Hello world</field>\n      </shadow>\n      <block type=\"node_properties\" id=\"BcIBs?%=ypB?Ritg]UX7\">\n        <field name=\"PROPERTY_NAME\">PATH</field>\n      </block>\n    </value>\n    <next>\n      <block type=\"node_send\" id=\"FUZ=O)cx}X$rVR|}@noO\">\n        <field name=\"OUTPUT_NR\">1</field>\n        <value name=\"MESSAGE_INPUT\">\n          <shadow type=\"node_msg\" id=\"X,6T+0~8X!$Xd?G}Q-Ot\"></shadow>\n        </value>\n      </block>\n    </next>\n  </block>\n  <block type=\"node_properties\" id=\"iaKLve.kPk`8Zi+Vo=En\" x=\"-662\" y=\"-487\">\n    <field name=\"PROPERTY_NAME\">PATH</field>\n  </block>\n</xml>","outputs":1,"timeout":"0","blocklyConfig":"46e073e1.66e10c","backpackContents":[],"noerr":0,"name":"","x":540,"y":420,"wires":[["489476d9e944bd5c"]]},{"id":"489476d9e944bd5c","type":"debug","z":"c53e793dd2f3be09","name":"Blockly output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":730,"y":420,"wires":[]},{"id":"46e073e1.66e10c","type":"blockly-config","language":"en","showTrashcan":true,"allowComments":true,"showZoomControl":true,"showMiniMap":true,"enableBackPack":true,"backpackContents":["{\"type\":\"object_create\",\"inline\":true,\"extraState\":\"<mutation xmlns=\\\"http://www.w3.org/1999/xhtml\\\" num_fields=\\\"1\\\"><field name=\\\"property name\\\"></field></mutation>\",\"fields\":{\"field1\":\"payload\"},\"kind\":\"BLOCK\"}","{\"type\":\"node_return_message\",\"fields\":{\"OUTPUT_NR\":\"1\"},\"inputs\":{\"MESSAGE_INPUT\":{\"shadow\":{\"type\":\"node_msg\"}}},\"kind\":\"BLOCK\"}","{\"type\":\"node_object_set\",\"inline\":true,\"inputs\":{\"object_field\":{\"shadow\":{\"type\":\"node_msg\"}},\"field_name\":{\"shadow\":{\"type\":\"text\",\"fields\":{\"TEXT\":\"payload\"}}},\"value_field\":{\"shadow\":{\"type\":\"text\",\"fields\":{\"TEXT\":\"\"}}}},\"kind\":\"BLOCK\"}","{\"type\":\"node_object_get\",\"extraState\":\"<mutation xmlns=\\\"http://www.w3.org/1999/xhtml\\\" action=\\\"GET\\\"></mutation>\",\"fields\":{\"action\":\"GET\"},\"inputs\":{\"object\":{\"shadow\":{\"type\":\"node_msg\"}},\"field_name\":{\"shadow\":{\"type\":\"text\",\"fields\":{\"TEXT\":\"payload\"}}}},\"kind\":\"BLOCK\"}"],"toolboxPosition":"left","renderer":"geras","theme":"dark","categories":[{"name":"Node-RED","files":["blockly-contrib/npm/node-red-contrib-blockly/lib/nodered/nodeRedBlocksCodeGen.js","blockly-contrib/npm/node-red-contrib-blockly/lib/nodered/nodeRedBlocksDefs.js","blockly-contrib/npm/node-red-contrib-blockly/lib/nodered/toolbox.xml","blockly-contrib/npm/node-red-contrib-blockly/messages/en.js"]},{"name":"Objects","files":["blockly-contrib/npm/node-red-contrib-blockly/lib/json/objectBlocksCodeGen.js","blockly-contrib/npm/node-red-contrib-blockly/lib/json/objectBlocksDefs.js","blockly-contrib/npm/node-red-contrib-blockly/lib/json/toolbox.xml","blockly-contrib/npm/node-red-contrib-blockly/messages/en.js"]},{"name":"Buffer","files":["blockly-contrib/npm/node-red-contrib-blockly/lib/buffer/bufferBlocksCodeGen.js","blockly-contrib/npm/node-red-contrib-blockly/lib/buffer/bufferBlocksDefs.js","blockly-contrib/npm/node-red-contrib-blockly/lib/buffer/toolbox.xml","blockly-contrib/npm/node-red-contrib-blockly/messages/en.js"]},{"name":"Date/time","files":["blockly-contrib/npm/@blockly%2Ffield-date/dist/date_compressed.js","blockly-contrib/npm/node-red-contrib-blockly/lib/datetime/dateTimeBlocksCodeGen.js","blockly-contrib/npm/node-red-contrib-blockly/lib/datetime/dateTimeBlocksDefs.js","blockly-contrib/npm/node-red-contrib-blockly/lib/datetime/toolbox.xml","blockly-contrib/npm/node-red-contrib-blockly/messages/en.js"]},{"name":"Timer","files":["blockly-contrib/npm/node-red-contrib-blockly/lib/timer/timerBlocksCodeGen.js","blockly-contrib/npm/node-red-contrib-blockly/lib/timer/timerBlocksDefs.js","blockly-contrib/npm/node-red-contrib-blockly/lib/timer/toolbox.xml","blockly-contrib/npm/node-red-contrib-blockly/messages/en.js"]},{"name":"Blockly extension","files":["blockly-contrib/npm/node-red-contrib-blockly/lib/extra/extraBlocksCodeGen.js","blockly-contrib/npm/node-red-contrib-blockly/lib/extra/extraBlocksDefs.js","blockly-contrib/npm/node-red-contrib-blockly/lib/extra/toolbox.xml","blockly-contrib/npm/node-red-contrib-blockly/messages/en.js"]},{"name":"Blockly standard","files":["blockly-contrib/npm/node-red-contrib-blockly/lib/basic/toolbox.xml"]}],"customizeToolbox":false,"name":""}]

I have put all my code changes (to support Blockly themes) in a separate branch on my Github repository. And I have described my changes in this issue.

If anybody wants to troubleshoot why these theme plugins mess up the Blockly workspace, all help is appreciated! If nobody jumps in, it will probably stay like this due to lack of free time...


FYI There's a slight issue >= 2.1.0 - any node with a function in it seems to have editing issues

Just editing issues - exisiting nodes work just fine - Bart is aware via github so discussion taking place there

1 Like

I have a Zoom session monday evening with Maribeth from the Blockly team to debug this, because the behaviour is far from expected. To be continued.

I didn't expect it this soon, but @ralphwetzel has been so kind to send me a pull request to fix my issue with the Blockly themes. Kudos to Ralph for this one :pray:

I have shameless copied Ralph's animation (from here) which shows how to change from the Classic to the Dark theme:


This feature is not available on NPM yet! I will create a new release when the Blockly team has solved Simon's problem.

Just installed Blockly 2.2.0 and getting this warning. Should I be concerned?

22 Oct 15:20:07 - [info] Windows_NT 10.0.19045 x64 LE
22 Oct 15:20:08 - [info] Loading palette nodes
22 Oct 15:20:09 - [warn] [Blockly] Registered invalid property name 'functionExternalModules'. Properties for this node must start with 'blockly'
22 Oct 15:20:09 - [info] Dashboard version 3.6.0 started at /ui
22 Oct 15:20:10 - [info] Settings file : C:\Users\Owner.node-red\settings.js
22 Oct 15:20:10 - [info] Context store : 'memoryOnly' [module=memory]

I keep the backend of the Blockly node in sync (as much as possible) with the core Function node. Perhaps I copied a bit too much code from the Function node (i.e. this statement):

    RED.nodes.registerType("Blockly",BlocklyNode, {
        dynamicModuleList: "libs",
        settings: {
            functionExternalModules: { value: true, exportable: true },
            functionTimeout: { value:0, exportable: true }

Perhaps I should just ditch the settings part. Not sure what it is used for, but I don't think we need it in the Blockly node. Then at least you get rid of the warning. But I don't think it can do any harm.

Removed that code and the waring is gone. Blockly node still works fine. Thank you for your help!

As head of QA testing department , I'll try to remember to check the log next time there's a change :slight_smile:

1 Like

Ah thanks a lot for the confirmation!
I have removed the settings property on Github (not on npm yet).

My congratulations with your promotion!
You earned it.
The right man for the right job:

Ok I had tonight the Zoom debug session with Maribeth. Very friendly lady!
But the behaviour of Blockly was totally unexpected for her too.
So she is going to install Node-RED and our blockly node locally, and trying to figure out what is going wrong. Hopefully she is able to find the root cause...

1 Like

@cymplecy Maritbeth has triggered an issue on the Blockly repo, containing the results from our Zoom session. One step at a time...

1 Like

Ok, it seems I underestimated a 'bit' the migration from Blockly 6.x (Javascript) to 10.x (Typescript)...

But thanks to a lot of help from @ralphwetzel, @cymplecy and some nice ladies from the Google Blockly team, together we managed to get the job done finally. As a result, version 2.3.0 is now available in the palette :champagne: :clinking_glasses: :gift:

The release notes can be found here.

P.S. Simon, the next time we meet again is to migrate to Blockly version 14.x :innocent:

I think you'll find we will be meeting a lot sooner than that....


Great work :slight_smile:
All my instances now running 2.3.0 :slight_smile:

1 Like