UI Customization
The ComPDFKit WebViewer UI is fully customizable. This page is the hub for the most common customization tasks. Each linked guide goes deeper with API signatures and examples.
The public customization surface lives on instance.UI after the viewer initializes:
const { UI } = window.instance;Customization at a glance
| Task | API | Guide |
|---|---|---|
| Add / remove / reorder toolbar buttons | UI.setHeaderItems(callback) | Header & Toolbar |
| Switch the active toolbar group | UI.setToolbarGroup(group) | Header & Toolbar |
| Add a custom left/right panel | UI.addPanel(panel) | Panels |
| Replace all panels | UI.setPanels(panels) | Panels |
| Open / close a panel or dialog | UI.openElement / UI.closeElement | Show / Hide Elements |
| Hide / show buttons (unmount from DOM) | UI.disableElements / UI.enableElements | Show / Hide Elements |
| Switch theme | UI.setTheme('dark') | Themes & Styles |
| Inject custom CSS | UI.setCustomStyle(css) | Themes & Styles |
| Switch language | UI.setLanguage('zh-CN') | Localization |
| Add a language | UI.addLanguage(lang) | Localization |
| Register a custom modal | UI.addCustomModal(options) | Custom Modals |
| Customize context menus | UI.annotationPopup, UI.textPopup, … | Popups |
| Activate a tool | UI.setActiveTool(dataElement) | Tools |
| Register a custom tool | UI.registerTool(tool, options) | Tools |
The element model
Almost every visible piece of the UI — panels, dialogs, toolbar buttons — is identified by a data-element string. These identifiers are centralized in packages/webview/src/constants/dataElements.js and used as keys throughout the Pinia stores (activeElements, disabledElements, activeElementsTab).
This means three families of APIs control visibility:
- Open / close (
openElement,closeElement) — toggles whether an element is currently shown (e.g. open the left panel). - Enable / disable (
enableElements,disableElements) — mounts or unmounts the element from the DOM entirely. Disabling a toolbar button removes it; it does not disable the underlying feature. - Active tab (
setActiveElementTab) — switches the active sub-tab inside a tabbed element (e.g. which left-panel tab is shown).
See Show / Hide Elements for details.
The toolbar model
The toolbar is defined declaratively in the headers state of the viewer store — a map of toolbar group → item-array. Groups include default (the main top bar) and toolbarGroup-View, toolbarGroup-Annotation, toolbarGroup-Form, toolbarGroup-Measurement, toolbarGroup-Sign, toolbarGroup-Security, toolbarGroup-Redaction, toolbarGroup-Compare, toolbarGroup-Editor, toolbarGroup-Document, and toolbarGroup-Separation.
Each item is a descriptor with a type (toolButton, actionButton, toggleElementButton, statefulButton, customElement, divider, spacer), a dataElement, an icon, and an onClick(viewerStore, documentStore) handler. UI.setHeaderItems(callback) hands you a mutable Header object with a chainable DSL (get, getHeader, insertBefore, insertAfter, delete, push, pop, unshift, shift, update) to mutate these arrays.
See Header & Toolbar.
The panel model
Panels are rendered through a generic Panel.vue shell and declared in the viewer store's genericPanels list. The default set includes leftPanel, rightPanel, stylePanel, pageModePanel, stampPanel, linkPanel, contentEditorPanel, colorSeparationPanel, and redactionPanel. Custom panels added via UI.addPanel render through the same shell, with a render function returning an HTMLElement.
See Panels.
Common recipes
Hide the print and download buttons
UI.disableElements(['printButton', 'downloadButton']);Open the left panel on the thumbnails tab
UI.openElement('leftPanel');
UI.setActiveElementTab('leftPanel', 'ThumbnailsButton'); // THUMBS tabAdd a custom toolbar button
UI.setHeaderItems(header => {
header.getHeader('default').push({
type: 'actionButton',
dataElement: 'my-export-btn',
label: 'Export',
onClick: () => { /* … */ },
});
});Switch to dark theme and Chinese
UI.setTheme('dark');
UI.setLanguage('zh-CN');Add a custom right-side panel
UI.addPanel({
dataElement: 'myPanel',
location: 'right',
render: () => {
const el = document.createElement('div');
el.textContent = 'Hello from my panel';
return el;
},
});
UI.openElement('myPanel');Advanced customization
Because the full UI source is open, you can go beyond the runtime APIs: fork the repository and modify components, stores, or the toolbar definition directly. The Components and State Management guides describe the internal structure you would touch.