How to Build a Vue.js PDF Viewer with PDF.js
This article was first published in October 2021 and was updated in November 2024.
Vue.js is a frontend JavaScript framework for building single-page applications (SPAs) and user interfaces (UIs), and it’s the second-most starred GitHub repository. It enables users to create rapid prototypes and build fast and reliable applications.
In this blog post, we’ll use Vue.js to create a PDF viewer with PDF.js. PDF.js is an open source JavaScript library that allows you to view PDF files in your browser.
In the first part, we’ll look at how to create the PDF viewer with an open source library. In the second part, we’ll provide a step-by-step guide on how to integrate the PSPDFKit Vue.js PDF viewer library into the Vue.js project. Our viewer library provides some benefits beyond what PDF.js provides, including:
- A prebuilt UI — Save time with a well-documented list of APIs when customizing the UI to meet your exact requirements.
- Annotation tools — Draw, circle, highlight, comment, and add notes to documents with 15+ prebuilt annotation tools.
- Multiple file types — Support client-side viewing of PDFs, MS Office documents, and image files.
- 30+ features — Easily add features like PDF editing, digital signatures, form filling, real-time document collaboration, and more.
- Dedicated support — Deploy faster by working 1-on-1 with our developers.
Introduction to PDF Viewers
PDF viewers are essential tools for enhancing user experience in web applications by allowing users to view and interact with PDF documents directly within the browser. This seamless integration eliminates the need to download files or open them in a separate application, saving time and creating a more cohesive experience.
Benefits of Using a PDF Viewer
A PDF viewer lets users view documents without leaving the current tab, which is particularly useful for applications where document interaction is frequent. PDF viewers typically offer features such as zoom, page navigation, and text selection, allowing users to interact with and read content more effectively.
PDF Viewer Options for Vue.js
For Vue.js developers, there are both open-source and commercial options available for implementing a PDF viewer:
-
Open-source libraries like PDF.js, vue-pdf, and pdfvuer offer essential functionality and are straightforward to integrate, making them suitable for basic document viewing needs.
-
Commercial solutions like Nutrient offer advanced features such as annotations, form filling, and real-time collaboration, providing a more feature-rich experience for complex applications.
This article will explore both open-source and commercial options, guiding you through building a Vue.js PDF viewer with PDF.js and integrating Nutrient for a more robust solution.
Requirements
To get started, you’ll need:
- Git
- Node.js (in this article, we’re using version 16.13.0)
- A package manager for installing Vue CLI and importing packages — you can use npm or yarn
Creating the PDF Viewer with Open Source Libraries
There are two main PDF.js wrappers available to make the task of creating a PDF viewer with Vue.js easier: vue-pdf
and pdfvuer
. Let’s look at their respective advantages and disadvantages and decide which one to use.
Advantages of Using vue-pdf
- It has around 163K monthly downloads on npm.
- It’s easy to use, and it has an easy setup.
Disadvantages of Using vue-pdf
- It currently doesn’t support Vue 3.
- The library owner isn’t responsive.
- When printing your files, you may get a bug. There’s been a solution for this since 2019, but the PR isn’t merged into the main branch.
- It’s not actively maintained.
- It lacks documentation and examples.
Advantages of Using pdfvuer
- It has around 22K monthly downloads on npm.
- It has support for Vue 2 and Vue 3.
Disadvantages of Using pdfvuer
- It lacks documentation and examples.
- It doesn’t have many options to customize your project.
In this blog post, we’ll use the pdfvuer
library because it supports both version 2 and version 3 of Vue.js.
Installing Vue CLI
To work with Vue.js, we need to install Vue CLI (command-line interface), which is standard tooling for Vue.js. It helps you create, build, and run Vue.js applications.
You can install the CLI using npm
, which comes with Node.js, or yarn
:
npm install -g @vue/cli
yarn global add @vue/cli
You can check the version of Vue by running the following:
vue --version
In this blog post, we’re using Vue CLI version 4.5.15.
Creating the Project for pdfvuer
Vue CLI gives us an easy way to create our projects by using the following command:
vue create pdfvuer-example
Here, we’re using the create
option with the name of the project we want to create (pdfvuer-example
).
It’ll then ask some configuration questions.
Select Default (Vue 3) ([Vue 3] babel, eslint) from the list.
Now, change the directory to pdfvuer-example
:
cd pdfvuer-example
Adding the pdfvuer Library
Run the command below to install the pdfvuer
library via npm
or yarn
. This will work with Vue 3:
npm install pdfvuer@next --save
yarn add pdfvuer@next
Displaying the PDF
Add your PDF document to the public
directory. You can use our demo document as an example.
Now, go to your App.vue
file inside the src
directory and add the following code:
<template> <pdf src="example.pdf" :page="1" /> </template> <script> import pdf from 'pdfvuer'; export default { components: { pdf, }, }; </script>
-
In the
script
tag, we’re importing and exporting thepdf
component from thepdfvuer
library. -
In the
template
tag, we’re creating apdf
element by passing thesrc
attribute with the name of the PDF file. We’re also passing thepage
attribute with the number of the page we want to display. It’ll show the first page of our document.
When you start the app, you’ll see the PDF rendered in the browser. Use the following command to run the project:
npm run serve
yarn serve
You can see the app running at http://localhost:8080/.
💡 Tip: You can access the source code for this project on GitHub.
As you can see, this library didn’t give us many options to customize the PDF viewer. We can only display the first page of our document, and there’s no way to navigate through the pages.
We’ll move on to the next part of the article to see how PSPDFKit for Web can help us.
Building a Vue.js PDF Viewer with PSPDFKit
PSPDFKit offers a versatile PDF library that can be used to build a Vue.js PDF viewer. It provides more than 30 out-of-the-box features, including:
-
Document editing (rotate, merge, split, and more)
-
And much more
You can integrate it into your new or existing Vue.js projects with a couple of steps.
Now, let’s go back to our tutorial and see how to integrate PSPDFKit into your Vue.js project.
-
Create a new Vue.js project for PSPDFKit integration:
vue create pspdfkit-vue-project
This will ask some configuration questions.
-
Select Default (Vue 3) ([Vue 3] babel, eslint) from the list, and change the directory to
pspdfkit-vue-project
:
cd pspdfkit-vue-project
Adding PSPDFKit
-
Install
pspdfkit
as a dependency withnpm
oryarn
:
npm install pspdfkit
yarn add pspdfkit
-
Now, we can start building our Vue.js project. First, let’s create a
js
directory under thepublic
directory. Go to your terminal and run:
mkdir -p public/js
-
Copy the PSPDFKit for Web library assets to the
public/js
directory:
cp -R ./node_modules/pspdfkit/dist/pspdfkit-lib public/js/pspdfkit-lib
This will copy the pspdfkit-lib
directory from within node_modules/
into the public/js/
directory to make it available to the SDK at runtime.
Displaying the PDF
-
Add the PDF document you want to display to the
public
directory. You can use our demo document as an example. -
Add a component wrapper for the PSPDFKit library and save it as
src/components/PSPDFKitContainer.vue
:
// src/components/PSPDFKitContainer.vue <template> <div class="pdf-container"></div> </template> <script> import PSPDFKit from 'pspdfkit'; export default { name: 'PSPDFKit', /** * The component receives the `pdfFile` prop, which is type of `String` and is required. */ props: { pdfFile: { type: String, required: true, }, }, /** * We wait until the template has been rendered to load the document into the library. */ mounted() { this.loadPSPDFKit().then((instance) => { this.$emit('loaded', instance); }); }, /** * We watch for `pdfFile` prop changes and trigger unloading and loading when there's a new document to load. */ watch: { pdfFile(val) { if (val) { this.loadPSPDFKit(); } }, }, /** * Our component has the `loadPSPDFKit` method. This unloads and cleans up the component and triggers document loading. */ methods: { async loadPSPDFKit() { PSPDFKit.unload('.pdf-container'); return PSPDFKit.load({ // To access the `pdfFile` from props, use `this` keyword. document: this.pdfFile, container: '.pdf-container', }); }, }, /** * Clean up when the component is unmounted so it's ready to load another document (not needed in this example). */ beforeUnmount() { PSPDFKit.unload('.pdf-container'); }, }; </script> <style scoped> .pdf-container { height: 100vh; } </style>
Let’s look at what’s happening in our component:
-
The
template
section is rendering adiv
with thepdf-container
class. This will help us declaratively bind the rendered DOM to the underlying component instance’s data. -
The
script
section is defining a Vue.js instance namedPSPDFKit
and creating methods for mounting, loading, and unloading PDF files into thepdf-container
. -
The
style
section is defining the height of the container.
-
Now, replace the contents of
src/App.vue
with the following:
// src/App.vue <template> <div id="app"> <label for="file-upload" class="custom-file-upload"> Open PDF </label> <input id="file-upload" type="file" @change="openDocument" class="btn" /> <PSPDFKitContainer :pdfFile="pdfFile" @loaded="handleLoaded" /> </div> </template> <script> import PSPDFKitContainer from '@/components/PSPDFKitContainer'; export default { data() { return { pdfFile: this.pdfFile || '/example.pdf', }; }, /** * Render the `PSPDFKitContainer` component. */ components: { PSPDFKitContainer, }, /** * Our component has two methods — one to check when the document is loaded, and the other to open the document. */ methods: { handleLoaded(instance) { console.log('PSPDFKit has loaded: ', instance); // Do something. }, openDocument() { // To access the Vue instance data properties, use `this` keyword. if (this.pdfFile) { window.URL.revokeObjectURL(this.pdfFile); } this.pdfFile = window.URL.createObjectURL( event.target.files[0], ); }, }, }; </script> <style> #app { text-align: center; color: #2c3e50; } body { margin: 0; } input[type='file'] { display: none; } .custom-file-upload { border: 1px solid #ccc; border-radius: 4px; display: inline-block; padding: 6px 12px; cursor: pointer; background: #4a8fed; padding: 10px; color: #fff; font: inherit; font-size: 16px; font-weight: bold; } </style>
-
In the
template
section, we have a file upload input and thePSPDFKitContainer
component.
Vue.js uses directives to handle some types of functionality. For the input field, we’re using the 'v-on' directive to attach an event listener to the element. In our case, it’s the 'change' event. There’s a shortcut to 'v-on' that removes the keyword and uses an '@' symbol instead.
v-on:change="openDocument" v-on:loaded="handleLoaded" // or @change="openDocument" @loaded="handleLoaded"
Similar to the input field, for the PSPDFKitContainer
component, we’re using the v-bind
directive to bind the pdfFile
property to the pdfFile
property of the component and attaching an event listener for the loaded
event:
<PSPDFKitContainer :pdfFile="pdfFile" @loaded="handleLoaded" />
-
In the
script
section, you can see the implementation of thehandleLoaded
andopenDocument
methods. Also, there’s a data function that returns thepdfFile
property.
The data keeps track of reactive state within the current component. It’s always a function and returns an object. The object’s top-level properties are exposed via the component instance.
-
In the
style
section, we have styles for custom file input, and there are some general styles for theapp
.
-
Start the app:
npm run serve
yarn serve
You can see the application running on localhost:8080
.
If you can’t see your PDF file rendered in the browser, make sure you actually uploaded a PDF file inside the public
directory.
In the demo application, we can open different PDF files by clicking the Open PDF button. We can add signatures, annotations, stamps, and more.
💡 Tip: All the finished code is available on GitHub. 😎 You can find the example code for Vue 2 in the
vue-2
branch.
Conclusion
In this tutorial, we looked at how to build both a Vue.js PDF viewer with an open source library and a PSPDFKit Vue.js PDF viewer that allows you to display and render PDF files in your Vue.js application.
We created similar how-to blog posts using different web frameworks and libraries:
- How to Build an Angular PDF Viewer with PDF.js
- How to Build a React PDF Viewer with PDF.js
- How to Build a jQuery PDF Viewer with PDF.js
- How to Build a Bootstrap 5 PDF Viewer with PDF.js
- How to Build an Electron PDF Viewer with PDF.js
- How to Build a TypeScript PDF Viewer with PDF.js
- How to Build a JavaScript PDF Viewer with PDF.js
Open source Vue.js libraries are good options if you want to build the UI and features yourself. However, this can get complicated easily, as you may not get the support you need. Opting for a commercial solution lets you focus on other areas of your business and move up the value chain.
At PSPDFKit, we offer a commercial, feature-rich, and completely customizable JavaScript PDF library that’s easy to integrate and comes with well-documented APIs to handle advanced use cases. Try it for free, or visit our demo to see it in action.
FAQ
How do I install pdfvuer in my Vue.js project?
You can install pdfvuer using npm with the command npm install pdfvuer@next --save
or with yarn using yarn add pdfvuer@next
.
What is the benefit of using PSPDFKit over pdfvuer?
PSPDFKit offers more than 30 features including annotation tools, PDF form filling, document editing, and real-time collaboration, along with dedicated support.
How can I display a PDF file using pdfvuer in a Vue.js application?
Add the pdfvuer library to your project, then use the <pdf>
component in your Vue template to display the PDF by specifying the src
attribute with the path to your PDF file.
How do I handle file uploads in the PSPDFKit Vue.js viewer?
Use a file input element to upload PDF files, create an object URL for the selected file, and pass it to the PSPDFKit component in your Vue.js application.