For the past few weeks, I've been working on adding PDF support to our Mediathread media analysis and annotation tool. Mediathread already works with images, video, and audio files, and we've been talking about making a PDF annotator within this tool for at least 5 years.

At the moment, Mozilla maintains the state of the art for rendering PDF files in JavaScript: PDF.js. This is what's used when you open a PDF file in Firefox. You can embed this viewer in any web application. I haven't found much documentation, but the pieces are all here in Mozilla's repository: https://github.com/mozilla/pdf.js
There is some documentation on how to use the PDF.js library in a web application, but I haven't found much on embedding and using Mozilla's viewer along with it. These are my notes I've discovered along the way, through sorting all this out.
If you're embedding this viewer inside a surrounding layout, it's best to use an iframe embed instead of just throwing these DOM elements inside the view. The viewer relies on some styling that makes it difficult to embed otherwise: https://github.com/mozilla/pdf.js/issues/11626
Here's an overview of the pieces you'll need:
-
web/viewer.html
Copy this file into your application — this contains all the DOM for the viewer interface. In other words, the toolbar containing search, navigation, etc.
-
web/viewer.css
Styling for the viewer — customize as needed.
-
web/viewer.js
The PDFViewerApplication code.
-
build/pdf.js
The main PDF.js library code.
-
build/pdf.worker.js
This is a helper script that's needed to load the PDF file in a separate thread.
-
build/generic/web/locale
Locale files that are created in the build process. Copy this directory to your setup and load the
locale.properties
file in the viewer template.
You need to connect all these pieces in your customized viewer.html
template.
See Mediathread's
viewer template for a working example.
You'll need to tell pdf.js which PDF to load:
<script> window.PDFViewerApplication.baseUrl = window.ASSET_URL; </script>
I'm creating an annotation tool on top of PDF.js,
so I need to run initialization code after the PDF.js
viewer is done starting up and loading the PDF.
You can use the PDFViewerApplication.initializedPromise
and the viewer's eventBus
like this, to start
any custom code at the right time:
// Wait for the PDFViewerApplication to initialize // https://stackoverflow.com/a/68489111/173630 PDFViewerApplication.initializedPromise.then(function() { PDFViewerApplication.eventBus.on('pagerendered', function(e) { // The viewer is done loading, put custom init code here. }); });
This should be enough to get you started. I hope to eventually get a guide into Mozilla's documentation to make this PDF Viewer more approachable.