PDF.js Express Plusplay_arrow

Professional PDF.js Viewing & Annotations - Try for free

side menu

Get Started

play_arrow

Learn more

play_arrow

Common use cases

play_arrow

Open a document

play_arrow

Save a document

play_arrow

Viewer

play_arrow

UI Customization

play_arrow

Annotations

play_arrow

Collaboration

play_arrow

Forms

play_arrow

Signature

play_arrow

Searching

play_arrow

Measurement

play_arrow

Compare

play_arrow

Advanced Capabilities

play_arrow

PDF.js Express REST API

play_arrow

Migration Guides

play_arrow

How to customize viewer

The following features are available in:

check

PDF.js Express Viewer

help_outline

PDF.js Express Viewer is a free viewer with limited capabilities compared to PDF.js Express Plus

check

PDF.js Express Plus

help_outline

PDF.js Express Plus is a commercial PDF SDK for viewing, annotating, signing, form filling and more

There are two ways of adding customization to PDF.js Express Web Viewer, the first way is by accessing the PDF.js Express instance within your app and the second is by using a config file, which is a stand-alone JavaScript file executed inside PDF.js Express's iframe.

What option should I choose

We'll start with a simple example Web App and show where you can make your customizations.

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <script src="/lib/webviewer.min.js"></script>
  </head>
  <body>
    <div id="viewer"></div>
    <script src="app.js"></script>
  </body>
</html>

App level customization

Listen to events on the viewer element and call functions on the varructed PDF.js Express instance. Generally this is the recommended way to customize PDF.js Express within your app.

The only time where this will not work is if you are hosting the PDF.js Express lib folder on a different server from the rest of your app. This causes the iframe to not be accessible directly from your app because it's on a different origin.

// app.js
// Instantiate PDF.js Express
WebViewer({
  path: 'lib',
  licenseKey: 'Insert commercial license key here after purchase',
  initialDoc: '/files/webviewer-demo-annotated.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { 
      documentViewer, 
      annotationManager, 
      Annotations 
    } = instance.Core;

    instance.UI.disableElements(['searchButton']);
    instance.UI.setTheme('dark');
    documentViewer.setMargin(20);

    documentViewer.on('documentLoaded', () => {
      // Add customization here
      // Draw rectangle annotation on first page
      const rectangle = new Annotations.RectangleAnnotation();
      rectangle.PageNumber = 1;
      rectangle.X = 100;
      rectangle.Y = 100;
      rectangle.Width = 250;
      rectangle.Height = 250;
      rectangle.Author = annotationManager.getCurrentUser();
      annotationManager.addAnnotation(rectangle);
      annotationManager.drawAnnotations(rectangle.PageNumber);
    });

    documentViewer.on('fitModeUpdated', fitMode => {
      console.log('fit mode changed');
    });
  });

Config file

You can organize your custom code in a separate JavaScript file that is executed in the context of the iframe. In this way, you have direct access to the iframe window and document, and you can use PDF.js Express's global methods directly. More details about config files can be found here.

Config files are recommended when you are hosting the PDF.js Express lib folder on a separate server from your application. Since the config file is executed directly in the iframe there are no cross origin issues.

// app.js
// Instantiate PDF.js Express
WebViewer({
  path: 'https://myotherserver.com/webviewer/lib',
  licenseKey: 'Insert commercial license key here after purchase'
  initialDoc: '/files/webviewer-demo-annotated.pdf',
  config: 'config.js' // path/to/your/config.js
}, document.getElementById('viewer'));
// config.js executed inside the iframe
instance.UI.addEventListener(instance.UI.Events.VIEWER_LOADED, () => {
  // documentViewer is a global inside the config file
  const annotManager = documentViewer.getAnnotationManager();

    // Add customization here
  documentViewer.setMargin(20);
  documentViewer.on('fitModeUpdated', fitMode => {
    console.log('fit mode changed');
  });

  instance.UI.disableElement('searchButton');
  instance.UI.setTheme('dark');
});

instance.UI.addEventListener(instance.UI.Events.DOCUMENT_LOADED, () => {
  const annotManager = documentViewer.getAnnotationManager();

  // Add customization here
  // Draw rectangle annotation on first page
  // "Annotations" can be directly accessed since we're inside the iframe
  const rectangle = new instance.Core.Annotations.RectangleAnnotation();
  rectangle.PageNumber = 1;
  rectangle.X = 100;
  rectangle.Y = 100;
  rectangle.Width = 250;
  rectangle.Height = 250;
  rectangle.Author = annotManager.getCurrentUser();
  annotManager.addAnnotation(rectangle);
  annotManager.drawAnnotations(rectangle.PageNumber);
});