Edit Table of Contents in a PDF - Showcase Demo Code Sample

Requirements
View Demo

Create accessible navigation with document outlines or table of contents. Add new outlines or edit them.


This demo allows you to:

  • Upload your own PDF file
  • Add or Edit Outlines or Table of Contents
  • Save edits and download updated PDF

Implementation steps
To add Table of Contents or Outlines capability in WebViewer:

Step 1: Choose your preferred web stack
Step 2: Add the ES6 JavaScript sample code provided in this guide

1// ES6 Compliant Syntax
2// Copilot name: GitHub Copilot, version: 1.0.0, model: GPT-4, version: 2024-06, date: 2025-10-23
3// File: showcase-demos/edit-table-of-contents/index.js
4
5import WebViewer from '@pdftron/webviewer';
6
7function initializeWebViewer() {
8 WebViewer(
9 {
10 path: '/lib',
11 initialDoc: 'https://apryse.s3.us-west-1.amazonaws.com/public/files/samples/Report_2011.pdf',
12 enableFilePicker: true, // Enable file picker to open files. In WebViewer -> menu icon -> Open File
13 fullAPI: true, // Enable the full PDFNet API
14 licenseKey: 'YOUR_LICENSE_KEY', // Replace with your license key
15 },
16 document.getElementById('viewer')
17 ).then((instance) => {
18
19 // Set the toolbar group to the Annotate tools
20 instance.UI.setToolbarGroup('toolbarGroup-Annotate');
21
22 instance.Core.documentViewer.addEventListener('documentLoaded', () => {
23 UIElements.pageNumber = 1;
24
25 // Set default coordinates
26 setDefaultCoordinates(instance);
27
28 // Customize the webviewer left panel
29 UIElements.customizeUI(instance);
30 });
31
32 console.log('WebViewer loaded successfully.');
33 }).catch((error) => {
34 console.error('Failed to initialize WebViewer:', error);
35 });
36}
37
38// Function to get the iframe context of WebViewer
39const getIframeContext = () => {
40 return (
41 document.getElementById('viewer')?.getElementsByTagName('iframe')?.[0]?.contentWindow
42 .instance || window.WebViewer.getInstance()
43 );
44};
45
46// Function to add a new outline to the PDF document
47window.addOutline = (instance) => {
48 const iframe = getIframeContext();
49 const PDFNet = iframe.Core.PDFNet;
50
51 const documentViewer = iframe.Core.documentViewer;
52
53 return PDFNet.runWithCleanup(async () => {
54 const doc = await documentViewer.getDocument().getPDFDoc();
55 const newOutline = await PDFNet.Bookmark.create(doc, UIElements.outlineName);
56
57 const page = await doc.getPage(UIElements.pageNumber);
58
59 const zoom = 1;
60
61 const dest = await PDFNet.Destination.createXYZ(page, UIElements.xCoordinate, UIElements.yCoordinate, zoom);
62
63 newOutline.setAction(await PDFNet.Action.createGoto(dest));
64
65 await doc.addRootBookmark(newOutline);
66
67 instance.UI.reloadOutline();
68
69 instance.UI.setActiveTabInPanel({ tabPanel: UIElements.tabPanel.dataElement, tabName: 'outlinesPanel' });
70 });
71};
72
73// Helper function to set default coordinates based on the page size
74window.setDefaultCoordinates = (instance) => {
75 const doc = instance.Core.documentViewer.getDocument();
76 const pageInfo = doc.getPageInfo(UIElements.pageNumber);
77 UIElements.xCoordinate = 0;
78 UIElements.yCoordinate = pageInfo.height;
79}
80
81//helper function to load the ui-elements.js script
82function loadUIElementsScript() {
83 return new Promise((resolve, reject) => {
84 if (window.UIElements) {
85 console.log('UIElements already loaded');
86 resolve();
87 return;
88 }
89 const script = document.createElement('script');
90 script.src = '/showcase-demos/edit-table-of-contents-in-a-pdf/ui-elements.js';
91 script.onload = function () {
92 console.log('✅ UIElements script loaded successfully');
93 resolve();
94 };
95 script.onerror = function () {
96 console.error('Failed to load UIElements script');
97 reject(new Error('Failed to load ui-elements.js'));
98 };
99 document.head.appendChild(script);
100 });
101}
102
103// Load UIElements script first, then initialize WebViewer
104loadUIElementsScript().then(() => {
105 initializeWebViewer();
106}).catch((error) => {
107 console.error('Failed to load UIElements:', error);
108});

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales