Build a Web Component for PDF.js and its Default Viewer

Full-featured PDF viewer for any framework

Oleksandr Shevchuk
3 min readMar 24, 2023
PDF.js + web components

Looking for a fast all-in-one solution for rendering PDFs? Check out this demo!

Intro

Recently I looked for a complex solution to view PDF files in a browser. I had some criteria:

  • Easy to install and ready to use
  • JavaScript-based
  • Framework agnostic
  • Compatible with all major browsers
  • Provided most frequency-used functions like zoom, rotation, pagination, text search, language, etc.
  • Maintainable and free

As it turned out there are a few interesting solutions like PDFObject with an embedding approach and a WASM-based library, but they didn’t match all criteria. After detailed research, I found Mozilla’s PDF.js viewer to be the best choice.

What is PDF.js and how to use it?

The PDF.js comes with a powerful rendering engine, is well-maintainable, and time-proven javascript library. Also, it has a built-in viewer with rich functionality and a cute interface. Furthermore, the Firefox browser still uses this viewer to render PDF files.

There are a few ways to install PDF.js in web applications but in the case of using the default viewer, you should use the prebuilt files. The prebuilt comes with each library release and includes the generic build of PDF.js and the viewer. In the example below, I will use the prebuilt, deployed on Mozilla’s site:

<iframe src="https://mozilla.github.io/pdf.js/web/viewer.html?file=compressed.tracemonkey-pldi-09.pdf" width="1280" height="900" frameborder="0" />

This example has high limitations and is quite useless in real applications. Because of CORS policy, you can open PDF files only from Mozilla’s origin.

Create your viewer

One thing you can do is move the PDF.js prebuilt to your origin. Download the files, place them to your origin, and specify the path to the viewer and your PDF file:

<iframe src="/path-to-prebuilt/web/viewer.html?file=/path-to-pdf-file/file.pdf" width="1280" height="900" frameborder="0" />

Nicely done! Now you can open PDF files from your origin. Additionally, you can pass some viewer options as well, see the PDF.js wiki page.

Use Web Components

Web components it’s a set of technologies (Custom Elements, HTML Templates, Shadow DOM, ES Modules), created for functionality encapsulation. They are reusable, framework agnostic, and have nice browser support. You can use them anywhere, in your React, Vue, or any other framework app, and even on static HTML pages.

Let's try to implement a web component for the viewer!

Firstly we need to createiframe and place it inside the template:

const template = document.createElement('template');
template.innerHTML = `
<iframe frameborder="0"
width="1280"
height="900">
</iframe>
`

Then create a custom element class. We going to watch the src attribute, where we can pass a path to the PDF file:


class PdfViewer extends HTMLElement {
constructor() {
super()
const shadowRoot = this.attachShadow({mode: 'open'})
shadowRoot.appendChild(template.content.cloneNode(true))
}
// Watch the 'src' attribute
get observedAttributes() {
return ['src']
}
// Update iframe when element is initialized
connectedCallback() {
this.updateIframeSrc()
}
// Update iframe when 'src' is changed
attributeChangedCallback(name) {
if (['src'].includes(name)) {
this.updateIframeSrc()
}
}
// Render iframe
updateIframeSrc() {
this.shadowRoot.querySelector('iframe').setAttribute(
'src',
`/path-to-prebuilt/web/viewer.html?file=${this.getAttribute('src') || ''}`
)
}
}
// Define custom element
window.customElements.define('pdf-viewer', PdfViewer)

Finally, place the element in your HTML markup:

<pdf-viewer src="/path-to-pdf-file/file.pdf"></pdf-viewer>

It works, awesome! Now we have a web component for displaying PDFs and we can change file URL dynamically! This is just a simple example if you want a more complex solution, look at this package:

Conclusion

Displaying PDFs in your web application could be successfully done by the PDF.js viewer. You can create your viewer from scratch, or use a web component, that simplifies PDF.js setup.

🙏 Hope that you just read an interesting and helpful story.

👏 If you like it just send a clap, I’ll be very excited to see your reaction!

👆Follow me to be the first who will see my new articles.

Thanks and BR Oleksandr

--

--