Annotation Guide
NPM SDK guide for creating annotations, synchronizing host metadata, selecting, changing visibility, deleting, and recovering safely.
This guide covers the NPM SDK annotation workflow. Mount the viewer, wait for viewer.ready(), open a document, and register annotation listeners before users can create markups.
Build annotation experiences around Canvas-confirmed lifecycle events, not only the initial NPM tool command.
- 1Open the document and subscribe to created, selected, and deleted events.
- 2Enable one documented annotation action through
viewer.tools.set({ action, enabled: true }). - 3Wait for the created event and retain its
guidbefore opening metadata UI or saving a host-side record. - 4Use the same identifier to synchronize host-list selection, visibility changes, and deletion.
- 5Clear the active tool after save, cancel, or switching to an incompatible mode.
The tool command starts placement but does not provide the created identifier. Treat the created event as the point at which the host can associate metadata with a markup. Use createdWithDetail only when the application needs its additional detail payload.
viewer.tools.set({ action: "TEXT", enabled: true })viewer.tools.set({ action: "PAINT_FREEHAND", enabled: true, style })viewer.tools.clear()viewer.annotations.on("created", handleCreated)viewer.annotations.on("createdWithDetail", handleCreatedDetail)
Store the identifier emitted by selected in host state. Select from the host list with viewer.annotations.select({ guid }); update the host list from the event when Canvas selection changes. Selection is fire-and-forget, so use events for confirmed UI synchronization.
viewer.annotations.on("selected", handleSelected)viewer.annotations.select({ guid })viewer.annotations.unselect()
Use viewer.annotations.setVisibility({ annotationIds, visible }) when the UI owns the visibility value. Check both updatedCount and missingAnnotationIds, because Canvas can return partial success when an identifier no longer exists.
viewer.annotations.hide({ annotationIds })viewer.annotations.show({ annotationIds })viewer.annotations.setVisibility({ annotationIds, visible })
Delete is fire-and-forget. Keep the markup and related host record until deleted confirms the outcome. When a user cancels a newly created but unsaved annotation, delete its captured guid, clear the active tool, and discard only pending metadata.
viewer.annotations.delete({ guid })viewer.annotations.on("deleted", handleDeleted)- Do not remove a saved host record until the deleted event identifies the matching annotation.
Use host-side guards to prevent metadata, visibility, or delete actions from targeting unknown or stale annotations.
- Keep pending state while a tool is active and ignore unrelated created events.
- Require a captured
guidbefore opening metadata for a new markup. - If a tool request fails, clear pending host state and show a retry action.
- Cancelling an unsaved markup clears the tool and removes only that pending annotation.
- Unsubscribe listeners and destroy the viewer when the route unmounts.
