Add Bookmarks to PDFs Showcase Demo Code Sample

Requirements
View Demo

Add bookmarks to quickly return to specific pages within your PDF document.

This demo allows you to:

  • Upload your own PDF document
  • Add bookmarks to quickly return to pages within the PDF document

Implementation steps
To add user bookmark capability with WebViewer:

Step 1: Get started with your preferred web stack for WebViewer
Step 2: Add the ES6 JavaScript sample code provided in this guide

Once you generate your license key, it will automatically be included in your sample code below.

License Key

1// ES6 Compliant Syntax
2// GitHub Copilot v1, Claude Sonnet 4 (Preview), 2025-09-17
3// File: showcase-demos/add-personal-bookmark-pdf/index.js
4
5
6import WebViewer from '@pdftron/webviewer';
7
8const licenseKey = 'YOUR_WEBVIEWER_LICENSE_KEY';
9
10// Function to initialize and load the WebViewer with user bookmarks feature
11function addUserBookmarks() {
12 const element = document.getElementById('viewer');
13 if (!element) {
14 console.error('Viewer div not found.');
15 return;
16 }
17
18 WebViewer({
19 path: '/lib',
20 initialDoc: 'https://apryse.s3.us-west-1.amazonaws.com/public/files/samples/Report_2011.pdf',
21 licenseKey: licenseKey,
22 enableFilePicker: true,
23 }, element).then(instance => {
24
25 instance.UI.enableFeatures([instance.UI.Feature.Initials]);
26
27 // Reset state on document change
28 instance.Core.documentViewer.addEventListener('documentLoaded', () => {
29 instance.UI.openElements(['tabPanel']);
30 instance.UI.setActiveTabInPanel({ tabPanel: 'tabPanel', tabName: 'bookmarksPanel' });
31 instance.UI.enableBookmarkIconShortcutVisibility();
32
33 setBookmarks({});
34 setBookmarkName('My Bookmark');
35 setPageNumber(1);
36 createBookmarkControls();
37 });
38
39 instance.UI.addEventListener('userBookmarksChanged', (e) => {
40 console.log('User bookmarks updated:', e.detail);
41
42 });
43 });
44}
45// Bookmarks state
46let bookmarks = {};
47
48//Usage: 'setBookmarks({ ...bookmarks, [pageNumber]: bookmarkName });'
49function setBookmarks(newBookmarks) {
50 bookmarks = newBookmarks;
51 // Optionally, update the UI or perform other actions here
52}
53
54// Page number state
55let pageNumber = 1;
56function setPageNumber(val) {
57 pageNumber = val;
58}
59
60// Bookmark name state
61let bookmarkName = 'My Bookmark';
62function setBookmarkName(val) {
63 bookmarkName = val;
64}
65
66// Error state
67let error = '';
68function setError(val) {
69 error = val;
70 // if empty, or null, hide error div
71 if (val && val !== '' && val.length !== 0) {
72 console.error('Bookmark Error:', val);
73
74 } else {
75 console.log('Clearing bookmark error');
76 }
77
78 const errorDiv = document.querySelector('#bookmark-error-div');
79 if (errorDiv) {
80 errorDiv.textContent = val;
81 errorDiv.style.display = 'block';
82 }
83}
84
85// Button enabled state
86let isButtonEnabled = true;
87function setIsButtonEnabled(enabled) {
88 isButtonEnabled = enabled;
89 const button = document.querySelector('.bookmark-add-btn');
90 if (button) {
91 button.disabled = !enabled;
92 }
93}
94
95// Function to create a new bookmark
96function createNewBookmark() {
97 const doc = WebViewer.getInstance().Core.documentViewer.getDocument();
98 const bookmarksObject = bookmarks;
99 const bookmarkName = document.querySelector('.bookmark-title-input').value || 'My Bookmark';
100 setPageNumber(document.querySelector('.bookmark-page-input').value || 1);
101
102 console.log('Creating new bookmark at page', pageNumber, 'with name', bookmarkName);
103
104 // validate bookmarksObject exists
105 if (!bookmarksObject) {
106 console.log('Bookmarks feature is not available.');
107 return;
108 }
109
110 // validate doc exists
111 if (!doc) {
112 console.log('Document is not loaded.');
113 return;
114 }
115
116 // validate pageNumber is valid
117 if (isNaN(pageNumber) || pageNumber < 1 || pageNumber > doc.getPageCount()) {
118 setError('Please enter a valid page number.');
119 } else {
120 bookmarks[pageNumber - 1] = bookmarkName;
121 WebViewer.getInstance().UI.importBookmarks(bookmarksObject);
122 setBookmarks({ ...bookmarksObject, [pageNumber - 1]: bookmarkName });
123 setIsButtonEnabled(true);
124 setError('');
125 }
126}
127
128// Function to created bookmark controls
129function createBookmarkControls() {
130 console.log('Loading bookmark controls');
131
132//Checking if controls already exist
133
134 const existingControls = document.getElementById('controls-container');
135 if (existingControls) {
136 resetBookmarkControls();
137 console.log('Bookmark controls already exist');
138 return;
139 }
140
141 // Create a container for all controls (label, dropdown, and buttons)
142 const controlsContainer = document.createElement('div');
143 controlsContainer.className = 'control-container';
144 controlsContainer.id = 'controls-container';
145 const element = document.getElementById('viewer');
146 if (!element) {
147 console.error('Viewer div not found.');
148 return;
149 }
150 element.insertBefore(controlsContainer, element.firstChild);
151
152 console.log('controls.js loaded, createBookmarkControls:', window.createBookmarkControls);
153 // Dynamically load controls.js if not already loaded
154 if (!window.createBookmarkControls) {
155 const script = document.createElement('script');
156 script.src = '/showcase-demos/add-personal-bookmark-pdf/controls.js';
157 script.onload = function () {
158 console.log('Loaded controls', createControls);
159 console.log('createNewBookmarks:', createNewBookmark);
160 console.log('resetBookmarkControls:', resetBookmarkControls);
161
162 createControls('controls-container', createNewBookmark, resetBookmarkControls);
163
164 };
165 document.head.appendChild(script);
166 }
167}
168
169function resetBookmarkControls() {
170
171 setBookmarks({});//Clear bookmarks state
172 setPageNumber(1);
173 setBookmarkName('My Bookmark');
174 setError('');
175 setIsButtonEnabled(true);
176
177 console.log('Bookmark controls reset');
178}
179
180// Initialize the WebViewer and add user bookmarks feature
181addUserBookmarks();
182
183
184

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales