---
title: "Annotated Examples"
---
A growing collection of fragments of example code...
## Right click menus
### Background menu
The main background menu (right-click on the canvas) is generated by a call to
`LGraphCanvas.getCanvasMenuOptions`. The standard way of editing this is to implement the `getCanvasMenuItems` method on your extension:
```javascript
app.registerExtension({
name: "MyExtension",
getCanvasMenuItems(canvas) {
const items = []
items.push(null) // inserts a divider
items.push({
content: "The text for the menu",
callback: async () => {
// do whatever
}
})
return items
}
});
```
### Node menu
When you right click on a node, the menu is similarly generated by `node.getExtraMenuOptions`.
The standard way is to implement the `getNodeMenuItems` method on your extension:
```javascript
app.registerExtension({
name: "MyExtension",
getNodeMenuItems(node) {
const items = []
// You can filter by node type if needed
if (node.comfyClass === "MyNodeClass") {
items.push({
content: "Do something fun",
callback: async () => {
// fun thing
}
})
}
return items
}
});
```
### Submenus
If you want a submenu, use the `submenu` property with an `options` array:
```javascript
app.registerExtension({
name: "MyExtension",
getCanvasMenuItems(canvas) {
const items = []
items.push({
content: "Menu with options",
submenu: {
options: [
{
content: "option 1",
callback: (v) => {
// do something with v
}
},
{
content: "option 2",
callback: (v) => {
// do something with v
}
},
{
content: "option 3",
callback: (v) => {
// do something with v
}
}
]
}
})
return items
}
});
```
## Capture UI events
This works just like you'd expect - find the UI element in the DOM and
add an eventListener. `setup()` is a good place to do this, since the page
has fully loaded. For instance, to detect a click on the 'Queue' button:
```Javascript
function queue_button_pressed() { console.log("Queue button was pressed!") }
document.getElementById("queue-button").addEventListener("click", queue_button_pressed);
```
## Detect when a workflow starts
This is one of many `api` events:
```javascript
import { api } from "../../scripts/api.js";
/* in setup() */
function on_execution_start() {
/* do whatever */
}
api.addEventListener("execution_start", on_execution_start);
```
## Detect an interrupted workflow
**Deprecated:** The API hijacking pattern shown below is deprecated and subject to change at any point in the near future. Use the official [extension hooks](/custom-nodes/js/javascript_hooks) and API event listeners where available.
A simple example of hijacking the api:
```Javascript
import { api } from "../../scripts/api.js";
/* in setup() */
const original_api_interrupt = api.interrupt;
api.interrupt = function () {
/* Do something before the original method is called */
original_api_interrupt.apply(this, arguments);
/* Or after */
}
```
## Catch clicks on your node
**Deprecated:** The node method hijacking pattern shown below is deprecated and subject to change at any point in the near future. Use the official [extension hooks](/custom-nodes/js/javascript_hooks) where available.
`node` has a mouseDown method you can hijack.
This time we're careful to pass on any return value.
```javascript
async nodeCreated(node) {
if (node?.comfyClass === "My Node Name") {
const original_onMouseDown = node.onMouseDown;
node.onMouseDown = function( e, pos, canvas ) {
alert("ouch!");
return original_onMouseDown?.apply(this, arguments);
}
}
}
```