Document Authoring 2.0 migration guide
In Document Authoring SDK 2.0, registered actions control most editor controls. Buttons and menu items that worked without registered actions in 1.22 now require them. The action list also determines which keyboard shortcuts are available.
If you don’t customize editor actions, you don’t need to make changes.
If you configure actions with editor.setActions() or ui.actions, review your setup in the sections below.
An action is a command, such as Bold or Copy Link. Its id identifies the command. Its handler performs the command. The SDK provides handlers for built-in commands; you provide handlers for custom commands.
Both setActions() and ui.actions take the complete list of actions for the editor. Calling setActions() replaces the existing list; it doesn’t add to it.
The examples assume an existing editor instance. Functions such as saveDocument, openLinkDialog, and openStylePicker represent functions in your application.
How to keep built-in actions when adding custom commands
In version 1.22, you could register only a custom Save action and still use many built-in buttons and menus:
editor.setActions([ { id: 'custom.save', label: 'Save', handler: saveDocument },]);In version 2.0, those built-in controls disappear if their actions aren’t in the list.
To add Save while keeping the built-in commands, include defaultActions:
import { defaultActions } from '@nutrient-sdk/document-authoring';
editor.setActions([ ...defaultActions, { id: 'custom.save', label: 'Save', handler: saveDocument },]);Use the same approach when setting ui.actions during editor creation.
The editor hides buttons and menu items whose actions aren’t registered. It keeps controls for registered actions visible but disables them when they can’t run.
This change affects toolbar buttons and menus, context-menu items, link controls, spelling suggestions, and comment insertion. Comment-panel commands, tracked-change decisions, and ruler gestures work as before in version 2.0. Native clipboard shortcuts, such as Control/Command-C, work without clipboard actions.
How to show fewer toolbar buttons
To hide toolbar buttons without removing their commands elsewhere in the editor, change the toolbar configuration instead of the action list.
This example keeps all default actions available but shows only Bold in the toolbar:
import { defaultActions } from '@nutrient-sdk/document-authoring';
editor.setActions(defaultActions);editor.setToolbarConfig({ items: [{ type: 'built-in', id: 'bold', builtInType: 'bold' }],});How to keep only selected commands
To limit commands throughout the editor, provide a custom action list. Include every action required by the controls you want to keep.
For example, this configuration keeps Bold and comment insertion:
editor.setActions([ { id: 'formatting.bold', label: 'Bold' }, { id: 'insert.comment', label: 'Add Comment' },]);These actions use the SDK’s built-in handlers. You don’t need to provide a handler.
Use the following table to identify the actions needed by other controls:
| Controls | Required action IDs |
|---|---|
| Clipboard and Delete context-menu items | edit.cut, edit.copy, edit.paste, edit.paste-without-formatting, edit.delete |
| Add Comment | insert.comment |
| Link toolbar Edit, Remove, and Copy | link.edit, link.remove, link.copy |
| Link context-menu commands | insert.link, link.edit, link.remove, link.open, link.copy |
| Object wrapping and stacking menus | object.set-wrapping, object.arrange |
| Field commands | field.update, field.change |
| Spelling suggestions | spellcheck.replace |
| Other built-in toolbar and table commands | Use their IDs from the upgraded defaultActions. |
Registering an action doesn’t guarantee that it’s enabled. Availability depends on the current selection, editor mode, and the action’s isEnabled() predicate. Document permissions still apply when the editor processes an edit.
Check your replacement handlers
Registering your own handler under a built-in action ID replaces the SDK’s handler. In version 1.22, some controls still used the SDK’s implementation. In version 2.0, those controls use your handler.
For example, suppose your formatting.bold handler opens a help dialog. Clicking Bold now opens that dialog. It doesn’t apply bold formatting directly.
A replacement handler must perform the entire operation.
If it performs another task, give it a custom action ID and keep the built-in action for its original command.
New IDs in 2.0.0 may clash with existing custom action IDs
Version 2.0 adds 46 built-in action IDs. If a custom action uses one of these IDs, the SDK treats its handler as a replacement for that built-in command.
For example, you might have added a link.copy action in 1.22 to open your application’s link dialog:
editor.setActions([ { id: 'link.copy', label: 'Open link dialog', shortcuts: ['Mod+Shift+Y'], handler: openLinkDialog, },]);In 2.0, the built-in link.copy action copies a link’s URL. If you keep that ID for your dialog, the link toolbar and context-menu Copy controls run your handler instead.
Give the dialog its own ID to keep the SDK’s Copy command:
import { defaultActions } from '@nutrient-sdk/document-authoring';
editor.setActions([ ...defaultActions, { id: 'custom.open-link-dialog', label: 'Open link dialog', shortcuts: ['Mod+Shift+Y'], handler: openLinkDialog, },]);If a toolbar item refers to the old ID in actionId, update that reference too. The toolbar item’s id identifies the button, not the action, so you can keep it unchanged.
If you keep an ID that’s now built in, the replacement uses that command’s palette visibility, availability, and capabilities. This applies unless you override its public availability or capabilities. Some built-in commands are hidden from the palette; others remain visible. For example, link.copy is hidden, but layout.continue-numbering remains visible. Replacements for commands that list argument options are also hidden from the palette.
Check your other custom IDs against the new built-in action IDs. Use a custom. prefix to identify application-specific actions and reduce future ID conflicts.
Argument checks now apply to built-in handlers
When an action uses the SDK’s built-in handler, the SDK validates its arguments before running it.
Version 2.0 adds editor.executeAction() to run actions from your code and actionCalls to build calls to built-in actions. For example, style.apply requires a style ID from the current document:
import { actionCalls } from '@nutrient-sdk/document-authoring';
// `selectedStyleId` must be the ID of a style in the current document.await editor.executeAction(actionCalls['style.apply'](selectedStyleId));If the arguments are invalid, the promise rejects with a RangeError.
These argument checks apply only to built-in SDK handlers. Replacement handlers receive arguments without these checks and must validate them. Editor-mode restrictions and isEnabled() checks still apply.
Shortcuts and toolbar items that reference an action through actionId call it without arguments. A replacement handler can use this behavior to open a picker. This configuration replaces style.apply with your application’s openStylePicker function:
import { defaultActions } from '@nutrient-sdk/document-authoring';
editor.setActions([ ...defaultActions.filter(({ id }) => id !== 'style.apply'), { id: 'style.apply', label: 'Choose style', shortcuts: ['Mod+Shift+Y'], isEnabled: () => true, handler: openStylePicker, },]);With this replacement, every call to style.apply, including calls through executeAction(), runs openStylePicker. To keep the SDK’s style handler available, give the picker a separate custom action ID.
Update shortcuts that ran disabled actions
In version 2.0, keyboard shortcuts and toolbar buttons respect an action’s optional isEnabled() function. When it returns false, neither control can run the action. An action that requires selected text should return false when no text is selected.
In version 1.22, shortcuts ignored isEnabled(). In this example, the toolbar button was disabled, but the shortcut still called openPicker:
editor.setActions([ { id: 'custom.open-picker', label: 'Open picker', shortcuts: ['Mod+Shift+Y'], isEnabled: () => false, handler: openPicker, },]);In version 2.0, the shortcut is disabled too. Update isEnabled() to return true whenever the action can run. In this example, canOpenPicker() is an application function:
import { defaultActions } from '@nutrient-sdk/document-authoring';
editor.setActions([ ...defaultActions, { id: 'custom.open-picker', label: 'Open picker', shortcuts: ['Mod+Shift+Y'], isEnabled: () => canOpenPicker(), handler: openPicker, },]);If a toolbar button and a shortcut perform different tasks, assign each a separate action and isEnabled() check.
In version 2.0.0, web browsers don’t handle shortcuts when an action is disabled.
The editor still handles the registered shortcut when isEnabled() returns false, preventing the browser’s default behavior. To restore the browser behavior, remove the key combination from the action’s shortcuts and call setActions() with the updated action list.
New built-in action IDs
The following 46 action IDs have new built-in handlers in 2.0.
| Group | New IDs |
|---|---|
| Clipboard and deletion | edit.cut, edit.copy, edit.paste, edit.paste-without-formatting, edit.delete |
| Insertion | insert.comment, insert.field, insert.shape, insert.text-box |
| Links | link.edit, link.remove, link.open, link.copy |
| Objects and fields | object.arrange, object.set-wrapping, field.change, field.update |
| Spelling | spellcheck.replace |
| Lists and spacing | layout.apply-list-preset, layout.continue-numbering, layout.line-spacing-at-least, layout.line-spacing-exactly, layout.line-spacing-multiple |
| Page setup | layout.page-size, layout.page-orientation, layout.page-margin, layout.header-footer-different-first, layout.header-footer-different-odd-even, layout.header-footer-distance |
| Paragraph appearance | paragraph.set-shading, paragraph.set-border-color, paragraph.set-border-width, paragraph.set-border-radius |
| Shapes | shape.set-type, shape.set-fill-color, shape.set-fill-transparency, shape.set-outline-color, shape.set-outline-width, shape.set-outline-transparency, shape.set-text-padding, shape.set-wrapping |
| Styles | style.apply-clear, style.update |
| Tables | table.set-cell-border-width, table.set-cell-border-radius, table.set-wrapping |
The BuiltInActionId type also includes IDs for commands that already had built-in handlers in version 1.22. This table lists only commands with new built-in handlers in version 2.0.
For details about the new action APIs, refer to the actions and toolbar guide and the 2.0 release notes.