# The Unofficial Guide to the Interactive Tours API

**URL:** <https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977>\
**Category:** Developing Nodes\
**Tags:** tours, interactive\
**Created:** [9 May 2026 14:39 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977 "2026-05-09T14:39:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [9 May 2026 14:39 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977/1 "2026-05-09T14:39:40Z")

</div>

I Hope @knolleary & @dceejay don't mind me documenting this API, I know there is a view to develop some documentation on it when time allows, but I think this API deserves more exposure, so thought id share my DIY handbook on it for others.

Please do correct me on the below, if I have anything incorrect.

* * *

A node module can include interactive tours (like the one you see after a new Node RED release)  
Below is how you package one with your own Node module.

* * *

The Tour File contains an exported object, that contains a `steps` array, where each step object contains the following properties.

| Property | Use Case |
| --- | --- |
| `titleIcon` | _Optional_ **Font Awesome** Icon Identifier |
| `title` | _Optional_ title of the current step |
| `width` | _Optional_ width of the overlay |
| `description` | The content of the step (can be HTML) |
| `prepare()` | _Optional_ javascript to be executed prior to the step being executed |
| `complete()` | _Optional_ javascript to be executed after a step has finished and moved on |
| `element`, `direction` | Animates a halo/focus around this DOM element for this step |
| `wait` | Wait for this event before moving to the next step |

**Notes on `title`** and **`description`** ::

These must be per region code you have translation for

- en-US
- fr
- ja

etc etc

**Notes on `wait`** ::

When this is provided, the next button is hidden, as the sequence is only advanced to the next step once `wait` has been satisfied.

Example

```auto
wait: {
    type: "dom-event",
    event: "click",
    element: "#red-ui-workspace .red-ui-tab-button.red-ui-tabs-add a"
}

```

Using `wait` allows an interactive walkthrough of your node module.

**Notes on `element`** ::

This should be a jQuery selector path, along with the direction of the anchor, in which the `description` is displayed

Example

```auto
element: "#menu-item-arrange-menu-submenu",
direction: "left",

```

**Notes on `prepare`** and **`complete`** ::

Passing an argument of **done** , you can halt the remaining execution of the step until you call `done`

Example

```auto
prepare(done) {
    $('#zwjs-sidebar > div.red-ui-sidebar-header.zwjs-sb-menu-header > a:nth-child(1)').trigger('click')
    setTimeout(done, 250);
},

```

The trick with all this, is to carefully guide the user around the Node, and to ensure certain interaction has been triggered (interactively or in your `prepare` stages)

With all this in mind, the below

```js
/* ZwaveTour.js */
export default {
    steps: [{
            titleIcon: "fa wifi",
            title: {
                "en-US": "Welcome to Z-Wave JS for Node-RED",
            },
            description: {
                "en-US": "<p>Let's show you around the features.</p>",
            }
        },
        {
            title: {
                "en-US": "Here are the nodes that have been installed.",
            },
            prepare() {
                $('#red-ui-palette-container').scrollTop(100000)
            },
            element: '#red-ui-palette-base-category-ZWave_JS',
            description: {
                "en-US": `
                <ul>
                    <li>The Controller Node</li>
                    <li>The Device Node</li>
                    <li>The Event Splitter</li>
                    <li>The CMD Factory</li>
                </ul>`
            }
        },
        {
            title: {
                "en-US": "The Network Management Tab",
            },
            width: 400,
            prepare() {
                $('#red-ui-tab-zwave-js-link-button i').trigger('click')
            },
            element: '#zwjs-node-list > div > div > div',
            direction: 'left',
            description: {
                "en-US": 'This is where all advanced network management tasks can be accessed.'
            }
        },
        {
            title: {
                "en-US": "Node Information",
            },
            width: 400,
            prepare() {
                $('#zwjs-node-name-2').trigger('click')
            },
            element: '#zwjs-panel-stack > div:nth-child(3)',
            direction: 'left',
            description: {
                "en-US": 'Clicking a device in the list will show its details.'
            }
        },
        {
            title: {
                "en-US": "Advanced Panels",
            },
            width: 400,
            element: '#zwjs-sidebar > div.red-ui-sidebar-header.zwjs-sb-menu-header > a:nth-child(1)',
            direction: 'left',
            description: {
                "en-US": 'Both the selected node and network panels provide access to advanced operations.'
            }
        },
        {
            title: {
                "en-US": "Once opened, you have access to various advanced operations.",
            },
            width: 400,
            prepare(done) {
                $('#zwjs-sidebar > div.red-ui-sidebar-header.zwjs-sb-menu-header > a:nth-child(1)').trigger('click')
                setTimeout(done, 250);
            },
            element: '#red-ui-editor-stack > div > div.red-ui-tray-body-wrapper > div > div.zwjs-tray-menu',
            direction: 'right',
            description: {
                "en-US": 'The available operations depend on whether the advanced window was opened from a node or from the main network pane.'
            }
        },
        {
            title: {
                "en-US": "To close the panel, simply click the Close button.",
            },
            width: 400,
            element: '#zwjs-tray-close',
            prepare() {
                $('.red-ui-tourGuide-shade').css({
                    pointerEvents: 'none'
                })
            },
            direction: 'left',
            description: {
                "en-US": "Let's do it now."
            },
            wait: {
                type: "dom-event",
                event: "click",
                element: "#zwjs-tray-close"
            },
        },
        {
            title: {
                "en-US": "Have Fun!",
            },
            width: 400,
            description: {
                "en-US": "Please report any issues on my GitHub."
            }
        },
    ]
}

```

Does this.

![May-09-2026 15-33-36](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/a/aaa136e591859914c9a94be8dba9784b8501139b.gif)

So how to trigger the tour?

```js
/* Storing my tour using the resources API */
RED.tourGuide.run('/resources/<Module-Name>/Tours/ZwaveTour.js')

```

I hope this is helpful for the fellow Advanced Node developers, who are looking to add some really cool guided walkthroughs with your Nodes 🤓

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [9 May 2026 15:00 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977/2 "2026-05-09T15:00:48Z")

</div>

Thanks for that, Marcus. Currently, the API isn't fully open to third-party developers. Even though I also use it as a welcome tour. I also have a typing definition and some initial documentation for this API.

> <https://github.com/GogoVega/node-red/blob/33d83d016a0c990c5aed208056d19f0e52913015/packages/node_modules/%40node-red/editor-client/types/index.d.ts#L1734-L1838>

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [9 May 2026 15:02 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977/3 "2026-05-09T15:02:58Z")

</div>

Yup...

I spoke to Nick about it maybe a year ago, its available for use - just not yet documented in help material, so until such documentation exists, thought id share a usable guide until such a time

its an Awesome API and is pretty handy for advanced Nodes

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [9 May 2026 15:08 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977/4 "2026-05-09T15:08:51Z")

</div>

Quick technical note: the core is not (currently) protected against the simultaneous launching of tours. Then there's the debate of how to launch tours without it turning into a chaotic mess.

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [9 May 2026 15:12 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977/5 "2026-05-09T15:12:17Z")

</div>

The tours I am working, are not _auto triggered_, it will be from a user action _wanting_ to view the tour from the Side Panel.

Personally, I don't think 3rd party Nodes should be allowed to force a tour - but thats just MO, for 3rd party tours, I think it should be limited to executing it willingly and consciously.

---

<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 May 2026 15:36 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977/6 "2026-05-09T15:36:52Z")

</div>

> [@GogoVega](#):
>
> Quick technical note: the core is not (currently) protected against the simultaneous launching of tours. Then there's the debate of how to launch tours without it turning into a chaotic mess.

Which is one reason UIBUILDER does not use it. 😃

It has a simple notification if some data is available when a uibuilder version changes. It isn't perfect but it gets the job done and I don't think it conflicts (much?) with the Node-RED version tour.

> [@marcus-j-davies](#):
>
> I don't think 3rd party Nodes should be allowed to force a tour

You may be correct, however, some Node packages _may_ benefit (ahem) from at least some kind of user notification when their version is updated. 😃

Should any node devs want something simple, I'm happy to share.

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [9 May 2026 15:42 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977/7 "2026-05-09T15:42:29Z")

</div>

My intention for tours is to "kick start" users who have yet to understand (the fairly complex) set of Nodes and interaction it provides.

It's not really for those who already understands the offering if that makes sense.

- Im not good at writing - so tours is ideal for me

The Tours API is perfect for this I (rather then to showcasing changes), but yes... I have used the Notification API also - but didn't see it through.

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [9 May 2026 21:19 UTC](https://discourse.nodered.org/t/the-unofficial-guide-to-the-interactive-tours-api/100977/8 "2026-05-09T21:19:37Z")

</div>

Happy to consider a PR based on that - probably to fit in here somewhere - [node-red.github.io/docs/api/ui at master · node-red/node-red.github.io · GitHub](https://github.com/node-red/node-red.github.io/tree/master/docs/api/ui)
