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

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales