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 an 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.

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

License Key

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
Edit Table of Contents or Outlines in PDFs Showcase Demo | Apryse documentation