How to Use PDF.js in 2 Easy Steps

8 May 2020

author
Johan Johansson

In this article (a three-minute read), you’ll learn how to quickly embed a PDF in a web page using PDF.js, a popular open-source PDF viewer.

  1. Download and Extract the PDF.js Package
  2. Add the PDF viewer to your web page

Here’s an example of the PDF.js viewer we’re going to build:

We will also use it as a full screen PDF viewer where we can pass in a PDF filename via URL query string. Try the full screen viewer here:

Open Full Screen PDF.js Viewer

Step 1 - Download and Extract the PDF.js Package

Let’s head over to GitHub to download the latest stable release and then extract the contents inside our website folder.

Here are the contents of the .zip:

├── build/
│   ├── pdf.js
│   └── ...
├── web/
│   ├── viewer.css
│   ├── viewer.html
│   └── ...
└── LICENSE

After extracting the .zip contents, our website folder could look something like this:

├── index.html
├── subpage.html
├── assets/
│   ├── pdf/
|       ├── my-pdf-file.pdf
|       ├── my-other-pdf-file.pdf
|       ├── ...
├── build/                            - PDF.js files
│   ├── pdf.js
│   ├── ...
├── web/                              - PDF.js files
│   ├── viewer.css
│   ├── viewer.html
│   ├── ...
└── LICENSE                           - PDF.js license

Note: Due to browser security restrictions, PDF.js cannot open local PDFs using a file:// URL. You will need to start a local web server or upload the files to your web server.

Step 2 - Embed the PDF Viewer in Website

Our last step will be to embed the viewer in our web page by using an <iframe>. We will use a query string to tell the PDF viewer which PDF file to open. Like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Hello world!</title>
  </head>
  <body style="font-family: Arial, Helvetica, sans-serif;">

    <div style="width:760px;">
      <h2>About Us</h2>
      <p>We help software developers do more with PDFs. PDF.js Express gives a flexible and modern UI to your PDF.js viewer while also adding out-of-the-box features like annotations, form filling and signatures.</p>

        <!--
          Place the following <div> element where you want the PDF to be displayed in your website. You can adjust the size using the width and height attributes.
        -->
        <div>
            <iframe id="pdf-js-viewer" src="/web/viewer.html?file=%2assets%2pdf%2Fmy-pdf-file.pdf" title="webviewer" frameborder="0" width="500" height="600"></iframe>
        </div>

    </div>

  </body>
</html>

You’re done!

If you’d like to load PDF files from a different domain name, you will need to ensure the server hosting the PDFs has been set up for CORS.

Full Screen PDF Viewer

In addition to embedding the viewer in a page, we can also open it in a full screen:

Open Full Screen PDF.js Viewer

Here’s the code:

<a href="/web/viewer.html?file=%2Fmy-pdf-file.pdf">Open Full Screen PDF.js Viewer</a>

Just change the file query string parameter to open whatever you PDF you wish to open.

Customizing the PDF.js Toolbar

We can also reorganize the toolbar by moving elements around, removing buttons, and changing the icons.

Let’s open public/lib/web/viewer.html and add the following to the <head> section:

<script src="customToolbar.js"></script>

Next, we’ll create customToolbar.js inside the public/lib/web folder and add the following code:

let sheet = (function() {
  let style = document.createElement("style");
  style.appendChild(document.createTextNode(""));
  document.head.appendChild(style);
  return style.sheet;
 })();
 function editToolBar(){
  //when the page is resized, the viewer hides and move some buttons around.
  //this function forcibly show all buttons so none of them disappear or re-appear on page resize
  removeGrowRules();

  /* Reorganizing the UI 
   the 'addElemFromSecondaryToPrimary' function moves items from the secondary nav into the primary nav
   there are 3 primary nav regions (toolbarViewerLeft, toolbarViewerMiddle, toolbarViewerRight) 
  */

  //adding elements to left part of toolbar
  addElemFromSecondaryToPrimary('pageRotateCcw', 'toolbarViewerLeft')
  addElemFromSecondaryToPrimary('pageRotateCw', 'toolbarViewerLeft')
  addElemFromSecondaryToPrimary('zoomIn', 'toolbarViewerLeft')
  addElemFromSecondaryToPrimary('zoomOut', 'toolbarViewerLeft')

  //adding elements to middle part of toolbar
  addElemFromSecondaryToPrimary('previous', 'toolbarViewerMiddle')
  addElemFromSecondaryToPrimary('pageNumber', 'toolbarViewerMiddle')
  addElemFromSecondaryToPrimary('numPages', 'toolbarViewerMiddle')
  addElemFromSecondaryToPrimary('next', 'toolbarViewerMiddle')

  //adding elements to right part of toolbar
  addElemFromSecondaryToPrimary('secondaryOpenFile', 'toolbarViewerRight')

  /* Changing icons */
  changeIcon('previous', 'icons/baseline-navigate_before-24px.svg')
  changeIcon('next', 'icons/baseline-navigate_next-24px.svg')
  changeIcon('pageRotateCcw', 'icons/baseline-rotate_left-24px.svg')
  changeIcon('pageRotateCw', 'icons/baseline-rotate_right-24px.svg')
  changeIcon('viewFind', 'icons/baseline-search-24px.svg');
  changeIcon('zoomOut', 'icons/baseline-zoom_out-24px.svg')
  changeIcon('zoomIn', 'icons/baseline-zoom_in-24px.svg')
  changeIcon('sidebarToggle', 'icons/baseline-toc-24px.svg')
  changeIcon('secondaryOpenFile', './icons/baseline-open_in_browser-24px.svg')

  /* Hiding elements */
  removeElement('secondaryToolbarToggle')
  removeElement('scaleSelectContainer')
  removeElement('presentationMode')
  removeElement('openFile')
  removeElement('print')
  removeElement('download')
  removeElement('viewBookmark')
 }
 function changeIcon(elemID, iconUrl){
  let element = document.getElementById(elemID);
  let classNames = element.className;
  classNames = elemID.includes('Toggle')? 'toolbarButton#'+elemID :
 classNames.split(' ').join('.');
  classNames = elemID.includes('view')? '#'+elemID+'.toolbarButton' : '.'+classNames
  classNames+= "::before";
  addCSSRule(sheet, classNames, `content: url(${iconUrl}) !important`, 0)
 }
 function addElemFromSecondaryToPrimary(elemID, parentID){
  let element = document.getElementById(elemID);
  let parent = document.getElementById(parentID);
  element.style.minWidth = "0px";
  element.innerHTML =''
  parent.append(element);
 }
 function removeElement(elemID){
  let element = document.getElementById(elemID);
  element.parentNode.removeChild(element);
 }
 function removeGrowRules(){
  addCSSRule(sheet, '.hiddenSmallView *', 'display:block !important');
  addCSSRule(sheet, '.hiddenMediumView', 'display:block !important');
  addCSSRule(sheet, '.hiddenLargeView', 'display:block !important');
  addCSSRule(sheet, '.visibleSmallView', 'display:block !important');
  addCSSRule(sheet, '.visibleMediumView', 'display:block !important');
  addCSSRule(sheet, '.visibleLargeView', 'display:block !important');
 }
 function addCSSRule(sheet, selector, rules, index) {
  if("insertRule" in sheet) {
  sheet.insertRule(selector + "{" + rules + "}", index);
  }
  else if("addRule" in sheet) {
  sheet.addRule(selector, rules, index);
  }
 }
 window.onload = editToolBar

The PDF.js primary toolbar is broken down into 3 regions:

Screenshot: PDF.js Viewer Primary Toolbar Regions

The secondary toolbar is accessed via the chevron icon in the right region:

Screenshot: PDF.js Viewer Secondary Toolbar

We can move elements from the secondary toolbar into the left, middle, or right regions of the primary toolbar with the addElemFromSecondaryToPrimary function in customToolbar.js. For example, uncommenting this line will move the counter-clockwise rotation tool to the left region of the primary toolbar:

  addElemFromSecondaryToPrimary('pageRotateCcw', 'toolbarViewerLeft')

If you wanted to move pageRotateCcw to the middle region instead, you’d replace toolbarViewerLeft with toolbarViewerMiddle, or toolbarViewerRight for the right region. To move a different tool, replace the pageRotateCcw ID with the element ID you want to move. (See below for a full list of element IDs.)

We can also hide elements like this:

  removeElement('print')
  removeElement('download')

To hide different elements, replace print or download with the element ID.

NOTE: Hiding the download and print buttons is not a bulletproof way to protect our PDF, because it’s still possible to look at the source code to find the file. It just makes it a bit harder.

We can also customize the icons for various tools by swapping out the SVG file, like this:

changeIcon('previous', 'icons/baseline-navigate_before-24px.svg')

In the above example, previous is the element ID, while icons/baseline-navigate_before-24px.svg is the path to the tool icon.

And that’s it!

Element ID Reference for PDF.js User Interface Customization

Here’s handy reference with the IDs of the various toolbar icons:

Toolbar Icon ID
PDF Viewer UI Icon: sidebarToggle sidebarToggle
PDF Viewer UI Icon: viewFind viewFind
PDF Viewer UI Icon: pageNumber pageNumber
PDF Viewer UI Icon: numPages numPages
PDF Viewer UI Icon: zoomOut zoomOut
PDF Viewer UI Icon: zoomIn zoomIn
PDF Viewer UI Icon: next page next
PDF Viewer UI Icon: previous page previous
PDF Viewer UI Icon: presentationMode presentationMode
PDF Viewer UI Icon: openFile openFile
PDF Viewer UI Icon: print print
PDF Viewer UI Icon: download download
PDF Viewer UI Icon: viewBookmark viewBookmark
PDF Viewer UI Icon: secondaryToolbarToggle secondaryToolbarToggle
PDF Viewer UI Icon: scaleSelectContainer scaleSelectContainer
PDF Viewer UI Icon: secondaryPresentationMode secondaryPresentationMode
PDF Viewer UI Icon: secondaryOpenFile secondaryOpenFile
PDF Viewer UI Icon: secondaryPrint secondaryPrint
PDF Viewer UI Icon: secondaryDownload secondaryDownload
PDF Viewer UI Icon: secondaryViewBookmark secondaryViewBookmark
PDF Viewer UI Icon: firstPage firstPage
PDF Viewer UI Icon: lastPage lastPage
PDF Viewer UI Icon: pageRotateCw pageRotateCw
PDF Viewer UI Icon: pageRotateCcw pageRotateCcw
PDF Viewer UI Icon: cursorSelectTool cursorSelectTool
PDF Viewer UI Icon: cursorHandTool cursorHandTool
PDF Viewer UI Icon: scrollVertical scrollVertical
PDF Viewer UI Icon: scrollHorizontal scrollHorizontal
PDF Viewer UI Icon: scrollWrapped scrollWrapped
PDF Viewer UI Icon: spreadNone spreadNone
PDF Viewer UI Icon: spreadOdd spreadOdd
PDF Viewer UI Icon: spreadEven spreadEven
PDF Viewer UI Icon: documentProperties documentProperties

Next Steps

Now that you’ve got your PDF.js viewer up and running, consider the following tutorials:

Conclusion

As you can see, building a basic PDF viewer with PDF.js is pretty straightforward. If you require additional capabilities, like PDF annotation, filling forms, or e-signatures, consider PDF.js Express, which provides a PDF.js-based viewer with out-of-the-box annotation, PDF form fill, and signing.

PDF.js Express Demo

Check out the demo and let us know what you think!