Toolbar & ribbons
Add, remove, replace, or re-order toolbar actions without forking the viewer. Two complementary paths:
- Preset buttons +
ModularConfig— add buttons to the shipped ribbon UI. Best for most customizations. - Flat
ToolbarActioncontributions — for hosts / framework wrappers that render their own chrome and only need the viewer to aggregate actions and route events.
Add a button to the shipped UI
Register a preset button through a plugin, then reference it from the
config with a modularConfig transformer:
import { TruPDFSDK, type TruPDFPlugin } from '@trupdf/viewer';
const reviewPlugin: TruPDFPlugin = {
id: 'review-plugin',
presets: [
{
buttonType: 'markReviewedButton',
label: 'Mark reviewed',
icon: 'Check',
onActivate: ({ events }) => {
events.emit('plugin.toolbar.action', { id: 'mark-reviewed' });
},
},
],
modularConfig: (config) => ({
...config,
modularComponents: {
...config.modularComponents,
markReviewed: { type: 'presetButton', buttonType: 'markReviewedButton' },
},
modularHeaders: Object.fromEntries(
Object.entries(config.modularHeaders).map(([key, header]) =>
header.placement === 'top'
? [key, { ...header, items: [...header.items, 'markReviewed'] }]
: [key, header],
),
),
}),
};
const sdk = new TruPDFSDK({ plugins: [reviewPlugin] });See UI presets for the full
ModularConfig schema.
Flat toolbar contributions
For host-rendered chrome, contribute ToolbarActions:
import { TruPDFSDK, type ToolbarAction } from '@trupdf/viewer';
const markReviewed: ToolbarAction = {
id: 'mark-reviewed',
label: 'Mark reviewed',
icon: '✓', // string emoji or SVG
hotkey: 'Mod+R', // shortcut hint shown in tooltips
handler: () => store.markReviewed(currentPage()),
};
await sdk.install({ id: 'review-plugin', toolbar: [markReviewed] });
// Render them anywhere:
const actions = sdk.plugins.listToolbarActions();ToolbarAction fields: id, label, icon?, hotkey?,
handler(payload?).
Remove a built-in action
Use a ModularConfig and omit the action from the header's items
array. See UI presets.
Override a built-in
Preset registrations are last-write-wins, so a plugin preset with a
built-in buttonType replaces it everywhere the config references
that button:
await sdk.install({
id: 'my-print',
presets: [
{
buttonType: 'printButton', // replaces the built-in print preset
label: 'Print (legal)',
icon: 'Printer',
onActivate: () => openLegalPrintDialog(),
},
],
});Ribbon tabs
The shipped ribbon groups tools into tabs: annotation, shapes,
insert, measure, redact, edit, fill-sign, and
forms. Tab contents are ribbonItem / groupedItems entries in
the ModularConfig — re-order or trim them the same way as header
items.
Tool hotkeys
| Key | Tool |
|---|---|
| V | Select |
| E | Eraser |
| H | Highlight |
| U | Underline |
| K | Strikethrough |
| Q | Squiggly |
| I | Freehand ink |
| T | Free text |
| S | Sticky note |
| R | Rectangle |
| O | Ellipse |
| L | Line |
| A | Arrow |
| M | Rubber stamp |
| D | Distance |
| C | Count |
| X | Mark for redaction |
Single-letter, no modifier — suppressed while focus is in a text input. See Keyboard.
Listening for toolbar actions
sdk.events.on('plugin.toolbar.action', ({ id, payload }) => {
if (id === 'mark-reviewed') store.markReviewed(payload);
});Programmatic activation
Force a tool from code via the engine handed to engineRef:
const tools = engine.getToolController();
tools.setTool('highlight');
tools.setStyle({ color: { r: 1, g: 1, b: 0 } });Quick menus
The floating menus on top of selections are independent of the
toolbar and configured via two DocViewer props:
<DocViewer
source="…"
quickMenuItems={['comment', 'style', 'link', 'delete']} // default
textSelectionMenuItems={[
'copy',
'highlight',
'underline',
'strikethrough',
'squiggly',
'redact',
'link',
]} // default
/>Pass [] to hide either menu entirely. See Features →
Annotations for behaviour.