Add Personal Bookmarks to PDFs - Showcase Demo Code Sample

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 Personal Bookmark capability with WebViewer:

Step 1: Choose your preferred web stack
Step 2: Download any required modules listed in the Demo Dependencies section below
Step 3: Add the ES6 JavaScript sample code provided in this guide

Demo Dependencies
This sample uses the following:

Want to see a live version of this demo?

Try the Add Personal Bookmark PDF demo

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

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales