PDF Generation Template Editor
Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.
Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.
One key part of customizing the UI is the customization of the navigation bar. There are several ways you may want to customize the navigation bar. To name a few:
ComPDF for Web's WebViewer UI is built from modular components (headers, ribbon groups, grouped items and buttons) and provides flexible APIs for easy customization of the navigation bar.
To understand the structure of the navigation bar and the different types of tools, you can read The Composition of the Navigation Bar and Navigation Bar Tools. You can also jump directly to the UI Customization Samples to see examples of customizing the navigation bar.
The navigation bar is mainly divided into three parts: Navigation Tools, Feature Area, and the sub-menus of corresponding features (including sub-toolbars).
Navigation Tools: The icon buttons on the left and right sides of the image below (Navigation Bar) are the Navigation Tools. They are the items of the top header default-top-header, for example leftPanelButton, fullscreenButton, panToolButton, zoom-container, snippingToolButton, searchPanelToggle and menuButton.

Feature Area: The part inside the feature box in the middle of the navigation bar is called the Feature Area (as shown in the image below). Each feature has a different Sub-Menus. Buttons in both the Feature Area and the Sub-Menus can be modified individually. The Feature Area is the ribbon group default-ribbon-group, and each feature is a ribbon item whose dataElement is its toolbar group, such as toolbarGroup-View, toolbarGroup-Annotate, toolbarGroup-Forms, toolbarGroup-Measure, toolbarGroup-FillAndSign, toolbarGroup-Security, toolbarGroup-Redact, toolbarGroup-Compare, toolbarGroup-EditText, toolbarGroup-Document and toolbarGroup-Separation. 
Sub-Menus: Under different Feature Areas, there are corresponding Sub-Menus showing a group of tools for that feature. ComPDF for Web provides various APIs to customize the tools within this Sub-Menus. The Sub-Menus are shown in the header tools-header, and each one is a grouped items component, such as annotateGroupedItems and formsGroupedItems. Below, the Sub-Menus for annotations and forms are shown:


Find the Data Element Attribute of the Navigation Bar
To hide or show navigation bar elements, you first need to find the element’s data-element attribute in the DOM inspector.
For Example, the image below is the DOM of the Toolbar of the Feature Area.

We can see that their data-element value. Now we can use this value to hide or show it.
Hiding/Showing Navigation Bar Elements
// Hide the annotation button in the feature area.
instance.UI.disableElements('toolbarGroup-Annotate');
// Show the annotation button in the feature area.
instance.UI.enableElements('toolbarGroup-Annotate');// Hide the left panel button and the search button.
instance.UI.disableElements(['leftPanelButton', 'searchPanelToggle']);
// Show the left panel button and the search button.
instance.UI.enableElements(['leftPanelButton', 'searchPanelToggle']);You can call setToolbarGroup to switch between the different feature modes in the Feature Area.
import ComPDFKitViewer from "@compdfkit_pdf_sdk/webviewer";
const viewer = document.getElementById('webviewer');
ComPDFKitViewer({
path: '/',
initialDoc: 'Your PDF Url',
licenseKey: 'Input your license here'
}, viewer)
.then((instance) => {
// Set the current toolbar group.
instance.UI.setToolbarGroup('toolbarGroup-Annotate');
});Navigation Tools are modular components. You can add, remove, or move Navigation Tool buttons by getting a header with getModularHeader and calling its setItems method. The components are created with the classes in instance.UI.Components. If you would like to add custom tools to the navigation bar, it is crucial to understand what types of custom tools you need to add and which attributes to use. Below are the properties and types for Navigation Tools.
const { Components } = instance.UI;
instance.UI.getModularHeader('default-top-header').setItems([
new Components.ToolButton({
dataElement: 'panToolButton',
toolName: 'Pan',
}),
new Components.ToggleElementButton({
dataElement: 'searchPanelToggle',
toggleElement: 'searchPanel',
img: 'Search',
}),
new Components.Divider({ dataElement: 'myDivider' }),
new Components.CustomButton({
dataElement: 'myDownloadButton',
label: 'Download',
onClick: () => instance.UI.downloadPdf(),
}),
]);1. Set the Header
getModularHeader(dataElement) returns the header object. It provides getItems, setItems, getGroupedItems, setGap, setJustifyContent, setMaxWidth, setMaxHeight and setStyle to perform corresponding operations on navigation tools. getModularHeaderList() returns all headers, including the top header default-top-header and the sub-menu header tools-header.
// Get all items of the top header.
const items = instance.UI.getModularHeader('default-top-header').getItems();
console.log(items);2. Custom Button
A custom button can trigger an action. Clicking it does not toggle a selected state; use isActive to show it as selected. Its properties include:
data-element value of the button element. It can be used to disable/enable the element.Download or Search), path to an image, base64 data or an SVG string.instance.UI.updateElement(dataElement, { isActive }).desktop, tablet, mobile and small-mobile.const newCustomButton = new instance.UI.Components.CustomButton({
img: 'Search', // A built-in icon name. An image URL or an SVG string also works.
label: 'Alert',
onClick: () => {
alert('Hello world!');
},
dataElement: 'alertButton'
});
// Show the button as selected.
instance.UI.updateElement('alertButton', { isActive: true });3. State Button
The state button is a customizable button. You can decide how many states it has, what state is active, and when to update the state. Its properties include:
states object's keys.activeState. activeState is the object of the active state in states.update and activeState. activeState is the object of the active state in states. Call update() to update the button after changing activeState, or update(nameOfState) to switch to another state.update, the same function as in onClick.data-element value of the button element.desktop, tablet, mobile and small-mobile.Examples:
A stateful button that shows the count. When you click it, it will increment the counter by 1.
const countButton = new instance.UI.Components.StatefulButton({
initialState: 'Count',
states: {
Count: {
number: 1,
getContent: activeState => {
return activeState.number;
},
onClick: (update, activeState) => {
activeState.number += 1;
update();
}
}
},
dataElement: 'countButton'
});A state button showing the current page number. When you click it, the document will go to the next page. If you are on the last page, the document will turn to the first page.
const { documentViewer } = instance.Core;
const nextPageButton = new instance.UI.Components.StatefulButton({
initialState: 'Page',
states: {
Page: {
getContent: () => documentViewer.getCurrentPage(),
onClick: (update) => {
const currentPage = documentViewer.getCurrentPage();
const totalPages = documentViewer.getPageCount();
const atLastPage = currentPage === totalPages;
if (atLastPage) {
documentViewer.setCurrentPage(1);
} else {
documentViewer.setCurrentPage(currentPage + 1);
}
update();
}
}
},
mount: () => {
// Execute after mounting.
console.log('Mounted.');
},
unmount: () => {
// Execute before destruction.
console.log('Destroyed.');
},
dataElement: 'nextPageButton'
});4. Toggle Element Button
The toggle element button is used to open/close a specified UI element. When the UI element is open, the button is in an active state.
Its properties include:
data-element value of the button element. It can be used for showing/hiding that element.data-element value of the UI element to be opened/closed.Search or Pageset.desktop, tablet, mobile and small-mobile.const newToggleButton = new instance.UI.Components.ToggleElementButton({
img: 'Pageset',
toggleElement: 'pageModePanel',
dataElement: 'pageModePanelButton',
hidden: [ 'mobile' ]
});5. Tool Button
The tool button is the button in the sub-menus under the feature module. For example, in the Form feature mode, you can create a button for a text field function by customizing a tool button and specifying its tool name as TextFormFieldCreateTool. You can place the tool buttons you need to customize anywhere. When the tool is activated, the button is in an active state.
Its properties include:
data-element value of the button element. It can be used for showing/hiding that element.Pan, AnnotationCreateLine or TextFormFieldCreateTool.TextFieldIcon or LineTool. When it is not set, the icon registered with registerTool is used.desktop, tablet, mobile and small-mobile.const newToolButton = new instance.UI.Components.ToolButton({
toolName: 'TextFormFieldCreateTool',
img: 'TextFieldIcon',
dataElement: 'textfieldButton'
});6. Spacer
The spacer is an empty grouped items component with grow set to 1, used to occupy any remaining space in the tool. It is used to push buttons to each side of the default title.
Its properties include:
data-element value of the spacer.[].1 to occupy the remaining space.true to always show the spacer.desktop, tablet, mobile and small-mobile.const newSpacer = new instance.UI.Components.GroupedItems({
dataElement: 'newSpacer',
items: [],
grow: 1,
alwaysVisible: true,
hidden: [ 'mobile', 'small-mobile' ]
});7. Divider
Divider renders a vertical bar with some margin to separate item groups.
Its properties include:
data-element value of the divider.desktop, tablet, mobile and small-mobile.const newDivider = new instance.UI.Components.Divider({
dataElement: 'newDivider',
hidden: [ 'mobile', 'small-mobile' ]
});Add a custom save button:
const header = instance.UI.getModularHeader('default-top-header');
const mySaveButton = new instance.UI.Components.CustomButton({
dataElement: 'mySaveButton',
img: `<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 1L1 13" stroke="#BABABA" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1 1L13 13" stroke="#BABABA" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>`,
onClick: function() {
instance.UI.downloadPdf();
}
});
header.setItems([...header.getItems(), mySaveButton]);Hide the free text tool in the annotation sub-menus and put it on the right side of the navigation bar:
const { Components } = instance.UI;
const annotateItems = instance.UI.getGroupedItems('annotateGroupedItems');
const header = instance.UI.getModularHeader('default-top-header');
// get the free text tool.
const freetext = annotateItems.items.find(item => item.dataElement === 'freeTextToolButton');
annotateItems.setItems(annotateItems.items.filter(item => item !== freetext));
// add the line tool and the free text tool to the top header.
header.setItems([
...header.getItems(),
new Components.ToolButton({
toolName: 'AnnotationCreateLine',
img: 'LineTool',
dataElement: 'lineButton'
}),
freetext
]);Remove existing buttons from the top header, leaving only the ribbon:
const header = instance.UI.getModularHeader('default-top-header');
const items = header.getItems().filter(item => item.dataElement === 'default-ribbon-group');
header.setItems(items);Display and hide of bottom page box:
// Hide bottom page box.
instance.UI.disableElements('page-nav-floating-header');
// Show bottom page box.
instance.UI.enableElements('page-nav-floating-header');