Appearance
Overriding Dependency
@vue-pdf-viewer/viewer@^4.0.0 requires pdfjs-dist as a peer dependency with a default version of 5.4.530. This means you do not need to manually install pdfjs-dist unless you want to use a different version.
If your project relies on a specific version of pdfjs-dist that differs from the default, you can override by adding an override in your package.json.
You will need to make adjustments in 3 places:
- Change version in your
package.json - Configure
workerUrlofvite.config.{js,ts}in your Vue project ornuxt.config.{js,ts}in your Nuxt project - Change import path for
pdf.workerat the component setup
Step 1: package.json Configuration
Here’s how you can configure in your package.json:
json
{
"overrides": {
"pdfjs-dist": "desired-version"
}
}
// Reference: https://bun.sh/docs/install/overrides#overridesjson
{
"overrides": {
"@vue-pdf-viewer/viewer": {
"pdfjs-dist": "desired-version"
}
}
}
// Reference: https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overridesjson
{
"pnpm": {
"overrides": {
"pdfjs-dist": "desired-version"
}
}
}
// Reference: https://pnpm.io/package_json#pnpmoverridesjson
{
"resolutions": {
"@vue-pdf-viewer/viewer/pdfjs-dist": "desired-version",
}
}
// Reference: https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/Replace the "desired-version" with the version you prefer, for example, "4.10.38".
To ensure that your preferred pdfjs-dist is installed, you have to add pdfjs-dist to dependencies. Here’s how your package.json might look like:
json
{
"name": "your-vue-app",
"version": "1.0.0",
"dependencies": {
"@vue-pdf-viewer/viewer": "^1.1.0",
"pdfjs-dist": "4.10.38"
},
"overrides": {
"pdfjs-dist": "4.10.38"
}
}Step 2: Vite Configuration
When you change the version of pdfjs-dist, you need to configure the workerUrl for the component to use the new version. Additionally, ensure optimizeDeps is configured in your vite.config.{js,ts} to include pdfjs-dist.
Vue 3
vite.config.{js,ts}:
ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
optimizeDeps: {
include: ['pdfjs-dist'],
esbuildOptions: {
supported: {
'top-level-await': true
},
target: 'esnext'
}
}
});Nuxt
nuxt.config.{js,ts}:
ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: false },
vite: {
optimizeDeps: {
include: ['pdfjs-dist'],
esbuildOptions: {
supported: {
'top-level-await': true
},
target: 'esnext'
}
}
},
build: {
transpile: [
(ctx) => ctx.isServer ? 'pdfjs-dist': false,
(ctx) => ctx.isServer ? '@vue-pdf-viewer/viewer': false
],
},
})Step 3: Component Setup Configuration:
Make sure to adjust the import path for pdf.worker based on the version of pdfjs-dist you are using, as it might differ between versions.
vue
<script setup>
import { VPdfViewer } from '@vue-pdf-viewer/viewer'
import pdfWorker from 'pdfjs-dist/build/pdf.worker.min.mjs?url' // Adjust the path based on the `pdfjs-dist` version
</script>
<template>
<VPdfViewer :workerUrl="pdfWorker" src="..." />
</template>If your bundler cannot handle ?url imports, copy node_modules/pdfjs-dist/build/pdf.worker.min.mjs into your public/ directory and pass its path, e.g. <VPdfViewer workerUrl="/pdf.worker.min.mjs" src="..." />.
Content Security Policy >=4.4.0
The default PDF.js worker is a real JavaScript file served from your own origin. The library never uses data: or blob: URLs for it, so script-src and worker-src do not need data:, blob: or 'unsafe-inline'. The viewer's UI still injects its own stylesheet and inline icon images, so a complete policy for the viewer looks like this:
Content-Security-Policy: default-src 'self'; script-src 'self'; worker-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:Adjust the other directives to your application; the worker only requires script-src 'self' (and worker-src 'self' if you declare worker-src).
Bundle hosted on a different origin (CDN)
When your JavaScript bundle is served from another origin, PDF.js loads the worker through a small blob: module (this is PDF.js behaviour, not the library's). You then have two options:
- Allow it:
worker-src 'self' blob:and include the CDN origin inscript-src, or - Keep a strict policy by pointing
workerUrlat a copy of the worker on your own origin, see the recipe below.
Vite dev server
During vite dev, Vite pre-bundles dependencies into node_modules/.vite/deps. The library detects this and loads the worker from node_modules/@vue-pdf-viewer/viewer/dist/assets/ automatically. If you use a custom cacheDir or the worker fails to load in development only, exclude the library from pre-bundling:
ts
// vite.config.{js,ts}
export default defineConfig({
optimizeDeps: {
exclude: ['@vue-pdf-viewer/viewer']
}
})Production builds are not affected.
workerUrl and legacy browsers
Setting workerUrl disables the automatic legacy-worker fallback used for browsers without Promise.withResolvers. If you need both a custom worker and legacy support, point workerUrl at the legacy build, see Legacy Browser Support.
Bundlers without import.meta.url support and the CommonJS entry
The default worker is referenced as new URL('./assets/pdf.worker.min.mjs', import.meta.url), which Vite, Nuxt, webpack 5 and Rspack turn into an emitted asset. Bundlers that do not support this pattern (webpack 4, Parcel 1, esbuild with --bundle), a bundle hosted on a different origin (CDN), and browser code that loads the CommonJS entry (dist/index.cjs), cannot resolve it automatically. In those setups, pass workerUrl explicitly, pointing at the worker shipped with the library. It already matches the pinned pdfjs-dist, so no version bookkeeping is needed:
vue
<script setup>
import { VPdfViewer } from '@vue-pdf-viewer/viewer'
import pdfWorker from '@vue-pdf-viewer/viewer/assets/pdf.worker.min.mjs?url'
</script>
<template>
<VPdfViewer :workerUrl="pdfWorker" src="..." />
</template>If you also override the pdfjs-dist version, use the worker from that package instead, as mentioned earlier in Step 3.