Render PDFs on the browser using JavaScript

Most browsers these days support PDF rendering. In some cases, you may also need a PDF plugin to be installed. But what happens if you need to render PDFs on a closed system with no access to 3rd party plugins? How do you ensure that your solution can work consistently cross-browser? I recently worked on a project where we had to integrate a PDF viewer on a “closed” web application and this presented a new challenge. And who doesn’t love a good challenge? The requirements for the PDF viewer were as follows:

  • Should work cross-browser
  • Should support modern(ish) platforms
  • It shouldn’t rely on a PDF add-in to be installed.

In my search for the right solution, I came up across PDF.js. This is a tool created by the Mozilla team and provides native support for rendering PDFs within your page using pure vanilla JavaScript. The project is open source and you can check the source code here: Since the tool is all written in JavaScript, the solution will work without Adobe PDF Reader or any other PDF Readers installed on the target machine. The code to instantiate and display PDFs using pdf.js is surprisingly simple. However, as with everything else, there are some limitations/caveats:

  • It doesn’t support CORS
  • The documentation is bad/extremely limited
  • It doesn’t provide any support for navigation or other tooling around the PDF (printing, saving etc)

The first one means that you can only retrieve and display pdf documents that are on the same domain. If you site is running under, you can only get documents under that domain and trying to access a PDF document served at will fail. And the second is self-explanatory. Trying to implement the app takes a bit of an effort and you may need to poke into the source code. But we are developers so nothing new there. Finally, PDF.js may not provide any tooling, but it does come with a nice PDFViewer.html page which can be used instead to achieve the required results.
Show me the code:
To add PDF.js to your application, you’ll need to execute the following steps:

  • Download the code
  • Add the JavaScript code to instantiate the PDF.js library and pull the files
  • Add a progress handler and navigation (optional)
  • Done

Download the code

You can get the latest code in a zip file from this location: Unzip the folder. If you’re only interested in rendering the PDF and creating all the controls yourself, all you need to add is references to the following files:
- Pdf.js (in the /build/ folder) - Pdf.worker.js (in the /build/ folder) - Compatibility.js (in the /web/ folder) However, if you wish to take advantage of the pdfViewr, then you’ll need to add the whole (unzipped) folder into your application.

Add the JavaScript code

If you’ve decided to go with option one (render stuff and control the PDF rendering yourself), you’ll need to write some code to retrieve and render the document on a canvas HTML element. The following sample instantiates a renders a local PDF file to the page. I’ve also added an event handler for the progress and a reference to the total pages. You can use these as a starting point to add your own implementations for navigation and progress status.

The following URL shows an example using controls to navigate the PDF Document:

The easy way out

If you need a more complete solution for displaying your pdfs, you can use the following method once you’ve added the full, unzipped PDF.js folder to your solution. Create an iFrame or anything else that can use a URL as a source and supply a URL http:///web/viewer.html?file= => http://localhost/web/viewer.html?file=http://localhost/pdf.pdf

Node.js & NPM

For all you Node.js developers/fans, rest assured that you're covered as well. There is a nice npm package which will download all the necessary files to your solution. You can find details about the package here: However, if you're after the TL;DR version, then here you go:

npm install pdfjs-dist-for-node

Sample code to download

Get in Github:
I hope this gives you a way to display PDFs in a consistent way that works across all browsers.

  • Share this post on
comments powered by Disqus