The question is simple. How do I correctly import the PDF.js library into a Vuejs project?
The library is undefined
when I log it.
See my problem in a codesandbox live here.
This is how I am trying it now:
<script>
import pdfjsLib from "pdfjs-dist/build/pdf";
// import { PDFViewer } from "pdfjs-dist/web/pdf_viewer";
import "pdfjs-dist/web/pdf_viewer.css";
pdfjsLib.GlobalWorkerOptions.workerSrc =
"/[email protected]/build/pdf.worker.min.js";
export default {
name: "PdfViewer",
mounted() {
pdfjsLib.getDocument("./sample.pdf").then((doc) => {
console.log("doc: ", doc);
});
},
methods: {},
};
</script>
But that gives me the following error: Cannot read property 'GlobalWorkerOptions' of undefined
The question is simple. How do I correctly import the PDF.js library into a Vuejs project?
The library is undefined
when I log it.
See my problem in a codesandbox live here.
This is how I am trying it now:
<script>
import pdfjsLib from "pdfjs-dist/build/pdf";
// import { PDFViewer } from "pdfjs-dist/web/pdf_viewer";
import "pdfjs-dist/web/pdf_viewer.css";
pdfjsLib.GlobalWorkerOptions.workerSrc =
"https://cdn.jsdelivr.net/npm/[email protected]/build/pdf.worker.min.js";
export default {
name: "PdfViewer",
mounted() {
pdfjsLib.getDocument("./sample.pdf").then((doc) => {
console.log("doc: ", doc);
});
},
methods: {},
};
</script>
But that gives me the following error: Cannot read property 'GlobalWorkerOptions' of undefined
7 Answers
Reset to default 4I think the error occurs if pdfjsLib does not fall into the global scope , see also codesandbox :
<template>
<div id="pageContainer">
<div id="viewer" class="pdfViewer"></div>
</div>
</template>
<script>
import pdfjsLib from "pdfjs-dist/build/pdf";
import { PDFViewer } from "pdfjs-dist/web/pdf_viewer";
import "pdfjs-dist/web/pdf_viewer.css";
pdfjsLib.GlobalWorkerOptions.workerSrc =
"https://cdn.jsdelivr.net/npm/[email protected]/build/pdf.worker.min.js";
export default {
name: "PdfViewer",
props: { docPath: String },
mounted() {
this.getPdf();
},
methods: {
async getPdf() {
let container = document.getElementById("pageContainer");
let pdfViewer = new PDFViewer({
container: container,
});
let pdf = await pdfjsLib.getDocument(this.docPath);
pdfViewer.setDocument(pdf);
},
},
};
</script>
<style>
#pageContainer {
margin: auto;
width: 80%;
}
div.page {
display: inline-block;
}
</style>
use it:
<PdfViewer docPath="./sample.pdf" />
In case anyone else needs it, the soution is really simple. You just have to import it like this:
import * as pdfjsLib from "pdfjs-dist/build/pdf";
Pdf.js
provide a solution for us. Webpack.js included in the project.
const pdfjsLib = require("pdfjs-dist/webpack");
If you get an error like below:
./node_modules/pdfjs-dist/build/pdf.min.js 22:36927
Module parse failed: Unexpected token (22:36927)
Then we have to use es5/build/pdf.js
, so we can create src/pdfjs-webpack.js
:
"use strict";
var pdfjs = require("pdfjs-dist/es5/build/pdf.min.js");
var PdfjsWorker = require("worker-loader?esModule=false&filename=[name].js!pdfjs-dist/es5/build/pdf.worker.min.js");
if (typeof window !== "undefined" && "Worker" in window) {
pdfjs.GlobalWorkerOptions.workerPort = new PdfjsWorker();
}
module.exports = pdfjs;
then:
const pdfjsLib = require("../pdfjs-webpack");
vue-cli5
already use webpack5
, and webpack5
has a built-in web worker
and is very easy to use.
Create a file: pdfjs-webpack5.js
import * as pdfjsLib from 'pdfjs-dist'
pdfjsLib.GlobalWorkerOptions.workerPort = new Worker(new URL('pdfjs-dist/build/pdf.worker.js', import.meta.url))
export default pdfjsLib
According to the example getinfo.js
given in Setup PDF.js in a website
, you can easily read the contents of PDF files.
I use the version of the package.
pdfjs-dist: 2.15.349
webpack: 5.74.0
@vue/cli*: 5.0.8
I couldn't use the other answers, so I used viewer.html
inside an iframe.
- download the latest library from https://github.com/mozilla/pdf.js/releases
- Unzip it. Move the whole
pdfjs
directory inside thepublic
directory of your project. - Use this code inside your
vue
template.
<iframe
src="/pdfjs/web/viewer.html?file=/path-to-the-file.pdf"
:width="500px"
:height="500px"
frameborder="0"
></iframe>
You don't need to import anything inside the js.
If you looking for a more complete solution and prefer embedding with iframe
, consider using pdfjs-viewer-element
, the web component wrapper for PDF.js default viewer.
Vue has perfect support for Custom Elements, the only one thing you should do is tell your bundler that it is a web component, see Vue docs:
- Download PDF.js release, unzip, and copy the folder with files to the project.
- Install
pdfjs-viewer-element
:
npm install pdfjs-viewer-element
or using a browser:
<script type="module" src="https://cdn.skypack.dev/pdfjs-viewer-element"></script>
- Add web component with attributes to your page:
<pdfjs-viewer-element src="/file.pdf" viewer-path="/path-to-viewer"></pdfjs-viewer-element>
Where:
src
- Path to pdf file
viewer-path
- path to unpacked release folder
There are more attributes you can pass:
locale
- Specifies which language to use in the viewer UI
text-layer
- Text layer, that is used for text selection
page
- Page number
search
- Search text
phrase
- Search by phrase
zoom
- Zoom level
pagemode
- Page mode thumbs
viewer-css-theme
- Apply automatic, light or dark theme
viewer-extra-styles
- Add your CSS rules to the viewer application
See complete example: https://replit.com/@alekswebnet/Vue-3-pdfjs-viewer-element
There are usually two ways to integrate pdf.js: embedding with iframe or building from scratch based on the pdfjs-dist
.
If you have limited knowledge of the pdf.js project, it is better to use the iframe solution. However, the iframe solution may not be suitable if you require custom features, as it can be difficult to communicate with iframes and make the process more complicated. Building from scratch may seem like a good option initially, but if you want a fully-featured and performant PDF viewer like the default viewer provided by pdf.js, believe me, it requires a significant amount of work and the final result may not be as good.
I did some work and provide a third way to integrate the pdf.js default viewer to any project easily. You can use @document-kits/viewer
like a normal npm package, and you can quickly start a project in minutes use npm create
, now it support vue, lit and solid.
npm create @document-kits/viewer@latest my-app
# There will be prompt to let you choose a template to start,
# currently support lit, vue and solid.
cd my-app
# install dependencies
npm install
# run the dev server and open the default browser to view the demo
npm run dev --open
It still use the 3.x of pdf.js, I will upgrade to 4.x it I have time.