Recently, Vue.js’sGitHub Repository surpassed Facebook's React for number of stars. “Stars,” Github’s way to let users “like” and follow a repository, is hardly a precise measure of a repository’s popularity. But this was an interesting enough event to inspire me to dive into the framework and learn how it could work with WebViewer, our JavaScript PDF viewer . And I was pleasantly surprised by how easy it was to integrate.

If you’re looking to integrate Vue to display PDFs and enable viewing, signing, review and approval, redaction and more as part of your web app using Vue -- look no further. The following article guides you through how to add these capabilities and more, inside a single secure environment that can take care of version control as well. Additionally, you can check out the “How to add PDF viewing and editing to Vue 3 app with hooks” video for more information.

The source code for this project is available in our GitHub Repository here.


You just need Node.js installed. That's it.

(Feel free to skip ahead if you’re already a Vue expert.)

Install Vue CLI

Once you’ve installed Node.js, open up your terminal and type in the following to install the Vue CLI globally. It’s available here.

npm install -g @vue/cli

Now navigate to where you want the project to be created. You will then have two options: You can create and configure your project using a terminal, or the beautiful GUI.

If you want to use terminal type in:

vue create webviewer-vue-sample

If you want to use the GUI:

vue ui

Vue will then download all the necessary dependencies and create a project directory. For this example, we are sticking with the defaults. If you get stuck with any of the steps, you can check out the official documentation here.

Navigate into your project directory and open it with your preferred code editor.

Vue.JS App Structure

Inside of your project directory, it will be broken down into the following structure:


Assets inside this folder will be simply copied and not bundled by webpack. For example, favicon and index.html of our app live here.


This source directory contains assets and components, the building blocks of our application.

As a rule, most assets should be placed inside of src/assets. This ensures assets are minified and bundled together to eliminate extra network requests and embarrassing 404s, while ensuring old versions will not be cached. Store assets in the public folder only in a few situations, such as when you need a file with a specific name/structure in the build output.

To learn more about handling HTML and static assets inside of a Vue app, go here.


This tells the node package manager (npm) which dependencies need to be downloaded.

Adding WebViewer Component

Next, we will modify our Vue project to add WebViewer as a component, to use as our Vue PDF viewer. We’ll go through each file and modification in sequence.


Inside of package.json add two lines that will download WebViewer as a dependency to our project. Find the scripts section inside of package.json and add postinstall, download-webviewer scripts that will download WebViewer:

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "postinstall": "npm run download-webviewer",
    "download-webviewer": "npx @pdftron/webviewer-downloader"

By default, the WebViewer downloader will download and extract all the necessary files to public/lib. This is normally where we want them to be. However, if you would like to change the directory to -- for example -- public/webviewer/lib, you can do so by adding:

"download-webviewer": "npx @pdftron/webviewer-downloader --webviewerLocation ./public/webviewer/lib"

Note, it has to be inside of the public folder to preserve the folder structure. WebViewer is smart at only requesting the necessary resources when it needs to.


Inside of our index.html we need to add a script tag that points to webviewer.min.js:

<script src="<%= BASE_URL %>lib/webviewer.min.js"></script>

The BASE_URL variable is handled by the html-webpack-plugin and will change whether it is your local dev environment or production.


Create a new component called WebViewer.vue under src/components.

  <div ref='viewer'></div>

/* eslint-disable */
export default {
  name: 'WebViewer',
  props: {
    path: String,
    url: String
  mounted: function () {
            path: this.path,
            initialDoc: this.url, // replace with your own PDF file
          }, this.$refs.viewer).then((instance) => {
            // call apis here

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
div {
  width: 100%; 
  height: 100vh;

Here’s how the above code works:

The template section is responsible for binding the data and rendering the DOM to the Vue instance's data. In this case, we are adding our viewer div so we can mount WebViewer to use as our Vue PDF reader.

The script section allows us to declare WebViewer as a Vue component. It also lets us pass in the path to WebViewer’s lib folder location, as well as the initial PDF we want to load.

Next, inside the ‘mounted’ lifecycle method (which gets called when the element is mounted) we call the WebViewer constructor and use the passed-in properties.

When WebViewer is initialized, it returns an instance of WebViewer that can be used to call a number of useful APIs for document creation, manipulation, annotation, collaboration, redaction, and more.

Learn more about WebViewer’s comprehensive functionality by diving into the documentation . For example, WebViewer is capable of loading files from a URL , blob , file system and base64 data .

Lastly, the style section helps us apply custom CSS like width and height on the viewer’s div element which WebViewer gets mounted on.


Here we can add our newly created WebViewer component.

Inside of the template section, let us add our WebViewer component and pass in the path to WebViewer's lib folder and URL to a PDF we want to load.

  <div id="app">
    <WebViewer :path="`${publicPath}lib`" url=""/>

Inside of the script section, let’s import the WebViewer component and declare it in the export statement.

import WebViewer from './components/WebViewer.vue'
export default {
  name: 'app',
  components: {
  data () {
    return {
      publicPath: process.env.BASE_URL

Now, back in our terminal we can run npm install to install our dependencies and download the WebViewer.

cd webviewer-vue-sample
npm install

After the command finishes, you can start your application by running:

npm run serve

To “vue” your app (pun intended), navigate to http://localhost:8080!


In this blog, we showed you how to do add PDFTron's WebViewer inside of a Vue app using Vue CLI 3.3. The Vue framework is easy and fun to work with. We thank Vue team for their hard work!

You can download the complete working sample here on GitHub.

To get started with PDFTron’s WebViewer download a free trial . If you have any questions about integrating PDFTron into your project, please feel free to contact us and we'll be more than happy to help!

You can reach out to me here via email.