---
title: "Notes panel control | Nutrient Web SDK"
canonical_url: "https://www.nutrient.io/guides/web/headless/notes-panel/"
md_url: "https://www.nutrient.io/guides/web/headless/notes-panel.md"
last_updated: "2026-05-15T19:10:05.084Z"
description: "Open and close the annotation notes panel programmatically with Nutrient Web SDK so you can trigger note editing from a custom UI button or keyboard shortcut."
---

# Programmatic notes panel

The annotation notes panel is the popup that displays and edits the textual note attached to an annotation. Nutrient Web SDK opens it automatically when the user clicks the notes button in the default UI, but you can also open and close it from your own code. That’s useful when you’ve replaced the annotation actions slot, added a custom toolbar button, or wired up a keyboard shortcut.

Looking for the visual side of this? See the `annotations.note` [slot](https://www.nutrient.io/guides/web/user-interface/ui-customization/supported-slots.md#annotations) for replacing the rendered notes popup. This page covers the programmatic open/close path you’ll call from elsewhere in your UI.

## When to use this

Reach for programmatic notes panel control when you need:

- A custom toolbar button on a host-app sidebar that says “Show note for selected annotation.”

- A keyboard shortcut your application defines that opens the notes panel without going through the default chrome.

- Bulk workflows that step through annotations and open the notes panel for each as part of a review flow.

- Restoring the panel state after a programmatic action that would otherwise close it.

## API reference

| Method                                         | Notes                                                                                                                             |
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `instance.openAnnotationNote(annotationOrId?)` | Opens the notes panel for the given annotation. Pass an `Annotation` or an annotation `id`, or omit to use the current selection. |
| `instance.closeAnnotationNote()`               | Closes the notes panel if it’s open. No-op otherwise.                                                                             |

`openAnnotationNote` is a no-op when there’s nothing to open, that is, when no argument is passed and nothing is selected.

These methods control the **notes panel** that appears alongside an annotation. They do not create or modify the underlying note content. To change the note’s text, see [annotation notes](https://www.nutrient.io/guides/web/annotations/customization/annotation-notes.md).

## Example: Open the notes panel from a custom toolbar button

This example wires a host-app button to open the notes panel for whatever annotation is currently selected. The button is disabled when the selection doesn’t support notes:

```js

const instance = await NutrientViewer.load({
  container: "#viewer",

  document: "contract.pdf"
});

const noteButton = document.getElementById("show-note");

const TYPES_WITHOUT_NOTES = [
  NutrientViewer.Annotations.WidgetAnnotation,
  NutrientViewer.Annotations.TextAnnotation,
  NutrientViewer.Annotations.NoteAnnotation,
  NutrientViewer.Annotations.CommentMarkerAnnotation
];

function syncNoteButton() {
  const selected = instance.getSelectedAnnotations();
  const annotation = selected && selected.size === 1? selected.first() : null;

  noteButton.disabled =!annotation ||
    TYPES_WITHOUT_NOTES.some((Type) => annotation instanceof Type);
}

instance.addEventListener("annotationSelection.change", syncNoteButton);
syncNoteButton();

noteButton.onclick = () => {
  instance.openAnnotationNote();
};

```

`WidgetAnnotation`, `TextAnnotation`, `NoteAnnotation`, and `CommentMarkerAnnotation` don’t support notes, those types are excluded above.

## Example: Open the notes panel by annotation ID

When you have an annotation reference but it isn’t necessarily selected, pass the annotation or its `id`:

```js

const annotations = await instance.getAnnotations(0);
const target = annotations.find((a) => a.note);

if (target) {
  instance.openAnnotationNote(target);
}

```

You can also pass just the ID:

```js

instance.openAnnotationNote("01BS964AM5Z01J9MKBK64F22BQ");

```

This is convenient for review flows that step through annotations from a list without needing to select them in the viewer first.

## Example: Close the panel programmatically

Close the panel after a custom workflow runs — for example, after persisting a note to a backend:

```js

async function saveNoteAndClose(annotation, noteText) {
  const updated = annotation.set("note", noteText);
  await instance.update(updated);
  instance.closeAnnotationNote();
}

```

## Related

- [Annotation notes](https://www.nutrient.io/guides/web/annotations/customization/annotation-notes.md) — Creating and editing the underlying note text.

- [Note annotations](https://www.nutrient.io/guides/web/headless/note.md) — The sticky note annotation type, which is different from annotation notes.
---

## Related pages

- [Headless callout annotations](/guides/web/headless/callout.md)
- [Headless color presets](/guides/web/headless/color-presets.md)
- [Headless image annotations](/guides/web/headless/image.md)
- [Annotation clipboard](/guides/web/headless/clipboard.md)
- [Headless](/guides/web/headless.md)
- [Headless ink annotations](/guides/web/headless/ink.md)
- [Headless stamp annotations](/guides/web/headless/stamp.md)
- [Headless link annotations](/guides/web/headless/link.md)
- [Headless note annotations](/guides/web/headless/note.md)
- [Redactions from text selection](/guides/web/headless/redactions-from-selection.md)
- [Headless text annotations](/guides/web/headless/text-annotations.md)
- [Headless shape annotations](/guides/web/headless/shape.md)
- [Headless text markup](/guides/web/headless/text-markup.md)

